コード例 #1
0
        /// <summary>
        /// Insert user topic
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <returns>Insert user topic task</returns>
        public async Task InsertUserTopic(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle,
            string topicHandle)
        {
            TopicFeedEntity topicFeedEntity = new TopicFeedEntity()
            {
                AppHandle   = appHandle,
                TopicHandle = topicHandle,
                UserHandle  = userHandle
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.UserTopics);

            FeedTable  feedTable  = this.tableStoreManager.GetTable(ContainerIdentifier.UserTopics, TableIdentifier.UserTopicsFeed) as FeedTable;
            CountTable countTable = this.tableStoreManager.GetTable(ContainerIdentifier.UserTopics, TableIdentifier.UserTopicsCount) as CountTable;

            Transaction transaction = new Transaction();

            transaction.Add(Operation.Insert(feedTable, userHandle, appHandle, topicHandle, topicFeedEntity));
            transaction.Add(Operation.Insert(feedTable, userHandle, MasterApp.AppHandle, topicHandle, topicFeedEntity));
            transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, appHandle));
            transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, MasterApp.AppHandle));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #2
0
        /// <summary>
        /// Delete popular topic
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="timeRange">Time range</param>
        /// <param name="hostAppHandle">Hosting app handle: Master app or client app</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <param name="topicUserHandle">User handle</param>
        /// <returns>Delete popular topic task</returns>
        public async Task DeletePopularTopic(
            StorageConsistencyMode storageConsistencyMode,
            TimeRange timeRange,
            string hostAppHandle,
            string appHandle,
            string topicHandle,
            string topicUserHandle)
        {
            TopicRankFeedEntity topicRankFeedEntity = new TopicRankFeedEntity()
            {
                AppHandle   = appHandle,
                TopicHandle = topicHandle,
                UserHandle  = topicUserHandle
            };
            var serializedEntity = StoreSerializers.MinimalTopicRankFeedEntitySerialize(topicRankFeedEntity);

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics);

            Transaction   transaction = new Transaction();
            RankFeedTable topicsTable = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable;
            string        feedKey     = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle);

            transaction.Add(Operation.DeleteIfExists(topicsTable, ContainerIdentifier.PopularTopics.ToString(), feedKey, serializedEntity));

            if (timeRange != TimeRange.AllTime)
            {
                RankFeedTable expirationsTable = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsExpirationsFeed) as RankFeedTable;
                transaction.Add(Operation.DeleteIfExists(expirationsTable, ContainerIdentifier.PopularTopics.ToString(), feedKey, serializedEntity));
            }

            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #3
0
        /// <summary>
        /// Insert a new user-generated report of another user into the store
        /// </summary>
        /// <param name="storageConsistencyMode">consistency to use</param>
        /// <param name="reportHandle">uniquely identifies this report</param>
        /// <param name="reportedUserHandle">uniquely identifies the user who is being reported</param>
        /// <param name="reportingUserHandle">uniquely identifies the user doing the reporting</param>
        /// <param name="appHandle">uniquely identifies the app that the user is in</param>
        /// <param name="reason">the complaint against the content</param>
        /// <param name="lastUpdatedTime">when the report was received</param>
        /// <param name="hasComplainedBefore">has the reporting user complained about this user before?</param>
        /// <returns>a task that inserts the report into the store</returns>
        public async Task InsertUserReport(
            StorageConsistencyMode storageConsistencyMode,
            string reportHandle,
            string reportedUserHandle,
            string reportingUserHandle,
            string appHandle,
            ReportReason reason,
            DateTime lastUpdatedTime,
            bool hasComplainedBefore)
        {
            // get all the table interfaces
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.UserReports);

            ObjectTable lookupTable               = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsLookup) as ObjectTable;
            ObjectTable lookupUniquenessTable     = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsLookupUniquenessByReportingUser) as ObjectTable;
            FeedTable   feedByAppTable            = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsRecentFeedByApp) as FeedTable;
            FeedTable   feedByReportedUserTable   = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsRecentFeedByReportedUser) as FeedTable;
            FeedTable   feedByReportingUserTable  = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsRecentFeedByReportingUser) as FeedTable;
            CountTable  countByReportedUserTable  = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsCountByReportedUser) as CountTable;
            CountTable  countByReportingUserTable = this.tableStoreManager.GetTable(ContainerIdentifier.UserReports, TableIdentifier.UserReportsCountByReportingUser) as CountTable;

            // create the two entities that will be inserted into the tables
            UserReportEntity userReportEntity = new UserReportEntity()
            {
                ReportedUserHandle  = reportedUserHandle,
                ReportingUserHandle = reportingUserHandle,
                AppHandle           = appHandle,
                Reason      = reason,
                CreatedTime = lastUpdatedTime
            };

            UserReportFeedEntity userReportFeedEntity = new UserReportFeedEntity()
            {
                ReportHandle        = reportHandle,
                ReportedUserHandle  = reportedUserHandle,
                ReportingUserHandle = reportingUserHandle,
                AppHandle           = appHandle
            };

            // do the inserts and increments as a transaction
            Transaction transaction = new Transaction();

            // the partition key is app handle for all tables so that a transaction can be achieved
            transaction.Add(Operation.Insert(lookupTable, appHandle, reportHandle, userReportEntity));
            transaction.Add(Operation.Insert(feedByAppTable, appHandle, appHandle, reportHandle, userReportFeedEntity));
            transaction.Add(Operation.Insert(feedByReportedUserTable, appHandle, reportedUserHandle, reportHandle, userReportFeedEntity));
            transaction.Add(Operation.Insert(feedByReportingUserTable, appHandle, reportingUserHandle, reportHandle, userReportFeedEntity));

            // if the reporting user has not previously reported this user, then increment counts
            if (!hasComplainedBefore)
            {
                string uniquenessKey = UniquenessObjectKey(reportedUserHandle, reportingUserHandle);
                transaction.Add(Operation.Insert(lookupUniquenessTable, appHandle, uniquenessKey, new ObjectEntity()));
                transaction.Add(Operation.InsertOrIncrement(countByReportedUserTable, appHandle, reportedUserHandle));
                transaction.Add(Operation.InsertOrIncrement(countByReportingUserTable, appHandle, reportingUserHandle));
            }

            // execute the transaction
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #4
0
        /// <summary>
        /// Update notifications status
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="readActivityHandle">Read activity handle</param>
        /// <param name="readNotificationsStatusEntity">Read notifications status entity</param>
        /// <returns>Update notifications status task</returns>
        public async Task UpdateNotificationsStatus(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle,
            string readActivityHandle,
            INotificationsStatusEntity readNotificationsStatusEntity)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Notifications);

            ObjectTable statusTable = this.tableStoreManager.GetTable(ContainerIdentifier.Notifications, TableIdentifier.NotificationsStatus) as ObjectTable;
            CountTable  countTable  = this.tableStoreManager.GetTable(ContainerIdentifier.Notifications, TableIdentifier.NotificationsCount) as CountTable;

            Transaction transaction = new Transaction();

            if (readNotificationsStatusEntity == null)
            {
                NotificationsStatusEntity notificationsStatusEntity = new NotificationsStatusEntity()
                {
                    ReadActivityHandle = readActivityHandle
                };

                transaction.Add(Operation.Insert(statusTable, userHandle, appHandle, notificationsStatusEntity));
            }
            else
            {
                readNotificationsStatusEntity.ReadActivityHandle = readActivityHandle;
                transaction.Add(Operation.Replace(statusTable, userHandle, appHandle, readNotificationsStatusEntity as NotificationsStatusEntity));
            }

            transaction.Add(Operation.InsertOrReplace(countTable, userHandle, appHandle, 0));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #5
0
        /// <summary>
        /// Insert notification
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="activityHandle">Activity handle</param>
        /// <param name="activityType">Activity type</param>
        /// <param name="actorUserHandle">Actor user handle</param>
        /// <param name="actedOnUserHandle">Acted on user handle</param>
        /// <param name="actedOnContentType">Acted on content type</param>
        /// <param name="actedOnContentHandle">Acted on content handle</param>
        /// <param name="createdTime">Created time</param>
        /// <returns>Insert notification task</returns>
        public async Task InsertNotification(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle,
            string activityHandle,
            ActivityType activityType,
            string actorUserHandle,
            string actedOnUserHandle,
            ContentType actedOnContentType,
            string actedOnContentHandle,
            DateTime createdTime)
        {
            ActivityFeedEntity activityFeedEntity = new ActivityFeedEntity()
            {
                ActivityHandle       = activityHandle,
                AppHandle            = appHandle,
                ActivityType         = activityType,
                ActorUserHandle      = actorUserHandle,
                ActedOnUserHandle    = actedOnUserHandle,
                ActedOnContentType   = actedOnContentType,
                ActedOnContentHandle = actedOnContentHandle,
                CreatedTime          = createdTime
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Notifications);

            FeedTable  feedTable  = this.tableStoreManager.GetTable(ContainerIdentifier.Notifications, TableIdentifier.NotificationsFeed) as FeedTable;
            CountTable countTable = this.tableStoreManager.GetTable(ContainerIdentifier.Notifications, TableIdentifier.NotificationsCount) as CountTable;

            // do an insert & increment in a transaction.
            // if a queue message for inserting a notification gets processed twice, then this transaction will generate
            // a storage exception on the second attempt (because the insert will fail with a conflict (409) http status)
            try
            {
                Transaction transaction = new Transaction();
                transaction.Add(Operation.Insert(feedTable, userHandle, appHandle, activityHandle, activityFeedEntity));
                transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, appHandle));
                await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
            }
            catch (StorageException e)
            {
                // ignore this exception only if item exists (error code 409 conflict)
                if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict)
                {
                    this.log.LogInformation("NotificationsStore.InsertNotification received a conflict on insert" + e.Message);
                }
                else
                {
                    throw e;
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Insert user
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="identityProviderType">Identity provider type</param>
        /// <param name="accountId">Account id</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="firstName">First name</param>
        /// <param name="lastName">Last name</param>
        /// <param name="bio">User bio</param>
        /// <param name="photoHandle">Photo handle</param>
        /// <param name="visibility">User visibility</param>
        /// <param name="createdTime">Created time</param>
        /// <param name="requestId">Request Id</param>
        /// <returns>Insert user task</returns>
        public async Task InsertUser(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            IdentityProviderType identityProviderType,
            string accountId,
            string appHandle,
            string firstName,
            string lastName,
            string bio,
            string photoHandle,
            UserVisibilityStatus visibility,
            DateTime createdTime,
            string requestId)
        {
            UserProfileEntity userProfileEntity = new UserProfileEntity()
            {
                FirstName       = firstName,
                LastName        = lastName,
                Bio             = bio,
                CreatedTime     = createdTime,
                LastUpdatedTime = createdTime,
                Visibility      = visibility,
                PhotoHandle     = photoHandle,
                ReviewStatus    = ReviewStatus.Active,
                RequestId       = requestId
            };

            AppFeedEntity appFeedEntity = new AppFeedEntity()
            {
                AppHandle = appHandle
            };

            LinkedAccountFeedEntity linkedAccountFeedEntity = new LinkedAccountFeedEntity()
            {
                IdentityProviderType = identityProviderType,
                AccountId            = accountId
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Users);

            ObjectTable profilesTable = this.tableStoreManager.GetTable(ContainerIdentifier.Users, TableIdentifier.UserProfilesObject) as ObjectTable;
            FeedTable   appsTable     = this.tableStoreManager.GetTable(ContainerIdentifier.Users, TableIdentifier.UserAppsFeed) as FeedTable;
            FeedTable   accountsTable = this.tableStoreManager.GetTable(ContainerIdentifier.Users, TableIdentifier.UserLinkedAccountsFeed) as FeedTable;
            Transaction transaction   = new Transaction();

            transaction.Add(Operation.Insert(profilesTable, userHandle, appHandle, userProfileEntity));
            transaction.Add(Operation.Insert(appsTable, userHandle, this.tableStoreManager.DefaultFeedKey, appHandle, appFeedEntity));
            transaction.Add(Operation.Insert(accountsTable, userHandle, this.tableStoreManager.DefaultFeedKey, identityProviderType.ToString(), linkedAccountFeedEntity));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #7
0
        /// <summary>
        /// Delete featured topic
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <returns>Delete featured topic task</returns>
        public async Task DeleteFeaturedTopic(
            StorageConsistencyMode storageConsistencyMode,
            string appHandle,
            string topicHandle)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.FeaturedTopics);

            FeedTable   table       = this.tableStoreManager.GetTable(ContainerIdentifier.FeaturedTopics, TableIdentifier.FeaturedTopicsFeed) as FeedTable;
            Transaction transaction = new Transaction();

            transaction.Add(Operation.Delete(table, ContainerIdentifier.FeaturedTopics.ToString(), appHandle, topicHandle));
            transaction.Add(Operation.Delete(table, ContainerIdentifier.FeaturedTopics.ToString(), MasterApp.AppHandle, topicHandle));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #8
0
        /// <summary>
        /// Delete user
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <returns>Delete user task</returns>
        public async Task DeleteUserProfile(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Users);

            ObjectTable profilesTable = this.tableStoreManager.GetTable(ContainerIdentifier.Users, TableIdentifier.UserProfilesObject) as ObjectTable;
            FeedTable   appsTable     = this.tableStoreManager.GetTable(ContainerIdentifier.Users, TableIdentifier.UserAppsFeed) as FeedTable;
            Transaction transaction   = new Transaction();

            transaction.Add(Operation.Delete(profilesTable, userHandle, appHandle));
            transaction.Add(Operation.Delete(appsTable, userHandle, this.tableStoreManager.DefaultFeedKey, appHandle));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #9
0
        /// <summary>
        /// Delete comment reply
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="commentHandle">Comment handle</param>
        /// <param name="replyHandle">Reply handle</param>
        /// <returns>Delete comment reply task</returns>
        public async Task DeleteCommentReply(
            StorageConsistencyMode storageConsistencyMode,
            string commentHandle,
            string replyHandle)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.CommentReplies);

            FeedTable  feedTable  = this.tableStoreManager.GetTable(ContainerIdentifier.CommentReplies, TableIdentifier.CommentRepliesFeed) as FeedTable;
            CountTable countTable = this.tableStoreManager.GetTable(ContainerIdentifier.CommentReplies, TableIdentifier.CommentRepliesCount) as CountTable;

            Transaction transaction = new Transaction();

            transaction.Add(Operation.Delete(feedTable, commentHandle, this.tableStoreManager.DefaultFeedKey, replyHandle));
            transaction.Add(Operation.Increment(countTable, commentHandle, this.tableStoreManager.DefaultCountKey, -1.0));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #10
0
        /// <summary>
        /// Delete popular user
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <returns>Delete popular user topic task</returns>
        public async Task DeletePopularUser(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle)
        {
            UserRankFeedEntity userRankFeedEntity = new UserRankFeedEntity()
            {
                AppHandle  = appHandle,
                UserHandle = userHandle
            };
            var serializedEntity = StoreSerializers.MinimalUserRankFeedEntitySerialize(userRankFeedEntity);

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularUsers);

            RankFeedTable table       = this.tableStoreManager.GetTable(ContainerIdentifier.PopularUsers, TableIdentifier.PopularUsersFeed) as RankFeedTable;
            Transaction   transaction = new Transaction();

            transaction.Add(Operation.DeleteIfExists(table, ContainerIdentifier.PopularUsers.ToString(), appHandle, serializedEntity));
            transaction.Add(Operation.DeleteIfExists(table, ContainerIdentifier.PopularUsers.ToString(), MasterApp.AppHandle, serializedEntity));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #11
0
        /// <summary>
        /// Insert recent topic
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <param name="topicUserHandle">User handle</param>
        /// <returns>Insert recent topic task</returns>
        public async Task InsertRecentTopic(
            StorageConsistencyMode storageConsistencyMode,
            string appHandle,
            string topicHandle,
            string topicUserHandle)
        {
            TopicFeedEntity topicFeedEntity = new TopicFeedEntity()
            {
                AppHandle   = appHandle,
                TopicHandle = topicHandle,
                UserHandle  = topicUserHandle
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.RecentTopics);

            FeedTable   table       = this.tableStoreManager.GetTable(ContainerIdentifier.RecentTopics, TableIdentifier.RecentTopicsFeed) as FeedTable;
            Transaction transaction = new Transaction();

            transaction.Add(Operation.Insert(table, ContainerIdentifier.RecentTopics.ToString(), appHandle, topicHandle, topicFeedEntity));
            transaction.Add(Operation.Insert(table, ContainerIdentifier.RecentTopics.ToString(), MasterApp.AppHandle, topicHandle, topicFeedEntity));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #12
0
        /// <summary>
        /// Insert topic comment
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <param name="commentHandle">Comment handle</param>
        /// <param name="commentUserHandle">Comment user handle</param>
        /// <returns>Insert topic comment task</returns>
        public async Task InsertTopicComment(
            StorageConsistencyMode storageConsistencyMode,
            string topicHandle,
            string commentHandle,
            string commentUserHandle)
        {
            CommentFeedEntity commentFeedEntity = new CommentFeedEntity()
            {
                CommentHandle = commentHandle,
                UserHandle    = commentUserHandle
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.TopicComments);

            FeedTable  feedTable  = this.tableStoreManager.GetTable(ContainerIdentifier.TopicComments, TableIdentifier.TopicCommentsFeed) as FeedTable;
            CountTable countTable = this.tableStoreManager.GetTable(ContainerIdentifier.TopicComments, TableIdentifier.TopicCommentsCount) as CountTable;

            Transaction transaction = new Transaction();

            transaction.Add(Operation.Insert(feedTable, topicHandle, this.tableStoreManager.DefaultFeedKey, commentHandle, commentFeedEntity));
            transaction.Add(Operation.InsertOrIncrement(countTable, topicHandle, this.tableStoreManager.DefaultCountKey));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #13
0
        /// <summary>
        /// Delete app
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="appHandle">App handle</param>
        /// <returns>Delete app task</returns>
        public async Task DeleteApp(
            StorageConsistencyMode storageConsistencyMode,
            string appHandle)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Apps);

            ObjectTable profilesTable          = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppProfilesObject) as ObjectTable;
            ObjectTable credentialsTable       = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppIdentityProviderCredentialsObject) as ObjectTable;
            ObjectTable validationConfigsTable = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppValidationConfigurationsObject) as ObjectTable;
            ObjectTable pushConfigsTable       = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppPushNotificationsConfigurationsObject) as ObjectTable;
            Transaction transaction            = new Transaction();

            transaction.Add(Operation.Delete(profilesTable, appHandle, appHandle));
            transaction.Add(Operation.Delete(credentialsTable, appHandle, IdentityProviderType.Facebook.ToString()));
            transaction.Add(Operation.Delete(credentialsTable, appHandle, IdentityProviderType.Microsoft.ToString()));
            transaction.Add(Operation.Delete(credentialsTable, appHandle, IdentityProviderType.Google.ToString()));
            transaction.Add(Operation.Delete(credentialsTable, appHandle, IdentityProviderType.Twitter.ToString()));
            transaction.Add(Operation.Delete(credentialsTable, appHandle, IdentityProviderType.AADS2S.ToString()));
            transaction.Add(Operation.Delete(validationConfigsTable, appHandle, appHandle));
            transaction.Add(Operation.Delete(pushConfigsTable, appHandle, PlatformType.Windows.ToString()));
            transaction.Add(Operation.Delete(pushConfigsTable, appHandle, PlatformType.Android.ToString()));
            transaction.Add(Operation.Delete(pushConfigsTable, appHandle, PlatformType.IOS.ToString()));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #14
0
        /// <summary>
        /// Insert popular user topic
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <param name="score">Entity value</param>
        /// <returns>Insert popular user topic task</returns>
        public async Task InsertPopularUserTopic(
            StorageConsistencyMode storageConsistencyMode,
            string userHandle,
            string appHandle,
            string topicHandle,
            long score)
        {
            TopicRankFeedEntity topicRankFeedEntity = new TopicRankFeedEntity()
            {
                AppHandle   = appHandle,
                TopicHandle = topicHandle,
                UserHandle  = userHandle
            };
            var serializedEntity = StoreSerializers.MinimalTopicRankFeedEntitySerialize(topicRankFeedEntity);

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularUserTopics);

            RankFeedTable table       = this.tableStoreManager.GetTable(ContainerIdentifier.PopularUserTopics, TableIdentifier.PopularUserTopicsFeed) as RankFeedTable;
            Transaction   transaction = new Transaction();

            transaction.Add(Operation.InsertOrReplace(table, userHandle, appHandle, serializedEntity, score));
            transaction.Add(Operation.InsertOrReplace(table, userHandle, MasterApp.AppHandle, serializedEntity, score));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #15
0
        /// <summary>
        /// Update user relationship
        /// </summary>
        /// <param name="storageConsistencyMode">Consistency mode</param>
        /// <param name="relationshipHandle">Relationship handle</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="relationshipUserHandle">Relationship user handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="userRelationshipStatus">Relationship status</param>
        /// <param name="lastUpdatedTime">Last updated time</param>
        /// <param name="readUserRelationshipLookupEntity">Read user relationship lookup entity</param>
        /// <param name="store">store object</param>
        /// <param name="lookupTable">lookup table</param>
        /// <param name="feedTable">feed table</param>
        /// <param name="countTable">count table</param>
        /// <returns>Update follower relationship task</returns>
        private async Task UpdateUserRelationship(
            StorageConsistencyMode storageConsistencyMode,
            string relationshipHandle,
            string userHandle,
            string relationshipUserHandle,
            string appHandle,
            UserRelationshipStatus userRelationshipStatus,
            DateTime lastUpdatedTime,
            IUserRelationshipLookupEntity readUserRelationshipLookupEntity,
            CTStore store,
            ObjectTable lookupTable,
            FeedTable feedTable,
            CountTable countTable)
        {
            string objectKey = this.GetObjectKey(appHandle, relationshipUserHandle);
            string feedKey   = this.GetFeedKey(appHandle, userRelationshipStatus);
            string countKey  = this.GetCountKey(appHandle, userRelationshipStatus);

            Transaction transaction = new Transaction();

            UserRelationshipFeedEntity relationshipFeedEntity = new UserRelationshipFeedEntity()
            {
                RelationshipHandle = relationshipHandle,
                UserHandle         = relationshipUserHandle
            };

            if (readUserRelationshipLookupEntity == null)
            {
                UserRelationshipLookupEntity newRelationshipLookupEntity = new UserRelationshipLookupEntity()
                {
                    RelationshipHandle     = relationshipHandle,
                    LastUpdatedTime        = lastUpdatedTime,
                    UserRelationshipStatus = userRelationshipStatus,
                };

                transaction.Add(Operation.Insert(lookupTable, userHandle, objectKey, newRelationshipLookupEntity));

                if (userRelationshipStatus != UserRelationshipStatus.None)
                {
                    transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                    transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, countKey));
                }
            }
            else
            {
                UserRelationshipStatus oldUserRelationshipStatus = readUserRelationshipLookupEntity.UserRelationshipStatus;
                string oldRelationshipHandle = readUserRelationshipLookupEntity.RelationshipHandle;

                readUserRelationshipLookupEntity.RelationshipHandle     = relationshipHandle;
                readUserRelationshipLookupEntity.UserRelationshipStatus = userRelationshipStatus;
                readUserRelationshipLookupEntity.LastUpdatedTime        = lastUpdatedTime;

                string oldFeedKey  = this.GetFeedKey(appHandle, oldUserRelationshipStatus);
                string oldCountKey = this.GetCountKey(appHandle, oldUserRelationshipStatus);

                transaction.Add(Operation.Replace(lookupTable, userHandle, objectKey, readUserRelationshipLookupEntity as UserRelationshipLookupEntity));

                if (userRelationshipStatus == oldUserRelationshipStatus)
                {
                    if (userRelationshipStatus != UserRelationshipStatus.None && relationshipHandle != oldRelationshipHandle)
                    {
                        transaction.Add(Operation.Delete(feedTable, userHandle, oldFeedKey, oldRelationshipHandle));
                        transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                    }
                }
                else
                {
                    if (userRelationshipStatus != UserRelationshipStatus.None)
                    {
                        transaction.Add(Operation.Insert(feedTable, userHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                        transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, countKey));
                    }

                    if (oldUserRelationshipStatus != UserRelationshipStatus.None)
                    {
                        transaction.Add(Operation.Delete(feedTable, userHandle, oldFeedKey, oldRelationshipHandle));
                        transaction.Add(Operation.Increment(countTable, userHandle, oldCountKey, -1.0));
                    }
                }
            }

            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #16
0
        /// <summary>
        /// Update like
        /// </summary>
        /// <param name="storageConsistencyMode">Consistency mode</param>
        /// <param name="likeHandle">Like handle</param>
        /// <param name="contentHandle">Content handle</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="liked">Like status</param>
        /// <param name="lastUpdatedTime">Last updated time</param>
        /// <param name="readLikeLookupEntity">Read like lookup entity</param>
        /// <returns>Update like task</returns>
        public async Task UpdateLike(
            StorageConsistencyMode storageConsistencyMode,
            string likeHandle,
            string contentHandle,
            string userHandle,
            bool liked,
            DateTime lastUpdatedTime,
            ILikeLookupEntity readLikeLookupEntity)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Likes);

            ObjectTable lookupTable = this.tableStoreManager.GetTable(ContainerIdentifier.Likes, TableIdentifier.LikesLookup) as ObjectTable;
            FeedTable   feedTable   = this.tableStoreManager.GetTable(ContainerIdentifier.Likes, TableIdentifier.LikesFeed) as FeedTable;
            CountTable  countTable  = this.tableStoreManager.GetTable(ContainerIdentifier.Likes, TableIdentifier.LikesCount) as CountTable;
            Transaction transaction = new Transaction();

            LikeFeedEntity likeFeedEntity = new LikeFeedEntity()
            {
                LikeHandle = likeHandle,
                UserHandle = userHandle
            };

            if (readLikeLookupEntity == null)
            {
                LikeLookupEntity newLikeLookupEntity = new LikeLookupEntity()
                {
                    LikeHandle      = likeHandle,
                    LastUpdatedTime = lastUpdatedTime,
                    Liked           = liked
                };

                transaction.Add(Operation.Insert(lookupTable, contentHandle, userHandle, newLikeLookupEntity));

                if (liked)
                {
                    transaction.Add(Operation.Insert(feedTable, contentHandle, this.tableStoreManager.DefaultFeedKey, likeHandle, likeFeedEntity));
                    transaction.Add(Operation.InsertOrIncrement(countTable, contentHandle, this.tableStoreManager.DefaultCountKey));
                }
            }
            else
            {
                bool   oldLiked      = readLikeLookupEntity.Liked;
                string oldLikeHandle = readLikeLookupEntity.LikeHandle;

                readLikeLookupEntity.LikeHandle      = likeHandle;
                readLikeLookupEntity.Liked           = liked;
                readLikeLookupEntity.LastUpdatedTime = lastUpdatedTime;

                transaction.Add(Operation.Replace(lookupTable, contentHandle, userHandle, readLikeLookupEntity as LikeLookupEntity));

                if (liked == oldLiked)
                {
                    if (liked && likeHandle != oldLikeHandle)
                    {
                        transaction.Add(Operation.Delete(feedTable, contentHandle, this.tableStoreManager.DefaultFeedKey, oldLikeHandle));
                        transaction.Add(Operation.Insert(feedTable, contentHandle, this.tableStoreManager.DefaultFeedKey, likeHandle, likeFeedEntity));
                    }
                }
                else
                {
                    if (liked)
                    {
                        transaction.Add(Operation.Insert(feedTable, contentHandle, this.tableStoreManager.DefaultFeedKey, likeHandle, likeFeedEntity));
                        transaction.Add(Operation.Increment(countTable, contentHandle, this.tableStoreManager.DefaultCountKey, 1));
                    }
                    else
                    {
                        transaction.Add(Operation.Delete(feedTable, contentHandle, this.tableStoreManager.DefaultFeedKey, oldLikeHandle));
                        transaction.Add(Operation.Increment(countTable, contentHandle, this.tableStoreManager.DefaultCountKey, -1.0));
                    }
                }
            }

            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #17
0
        /// <summary>
        /// Update topic follower relationship.
        /// Follower user : someone who follows the topic.
        /// </summary>
        /// <param name="storageConsistencyMode">Consistency mode</param>
        /// <param name="relationshipHandle">Relationship handle</param>
        /// <param name="topicHandle">topic handle</param>
        /// <param name="relationshipUserHandle">Relationship user handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicRelationshipStatus">Topic relationship status</param>
        /// <param name="lastUpdatedTime">Last updated time</param>
        /// <param name="readTopicRelationshipLookupEntity">Read topic relationship lookup entity</param>
        /// <returns>Update follower relationship task</returns>
        public async Task UpdateTopicFollowerRelationship(
            StorageConsistencyMode storageConsistencyMode,
            string relationshipHandle,
            string topicHandle,
            string relationshipUserHandle,
            string appHandle,
            TopicRelationshipStatus topicRelationshipStatus,
            DateTime lastUpdatedTime,
            ITopicRelationshipLookupEntity readTopicRelationshipLookupEntity)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.TopicFollowers);

            ObjectTable lookupTable = this.tableStoreManager.GetTable(ContainerIdentifier.TopicFollowers, TableIdentifier.TopicFollowersLookup) as ObjectTable;
            FeedTable   feedTable   = this.tableStoreManager.GetTable(ContainerIdentifier.TopicFollowers, TableIdentifier.TopicFollowersFeed) as FeedTable;
            CountTable  countTable  = this.tableStoreManager.GetTable(ContainerIdentifier.TopicFollowers, TableIdentifier.TopicFollowersCount) as CountTable;

            string objectKey = this.GetObjectKey(appHandle, relationshipUserHandle);
            string feedKey   = this.GetFeedKey(appHandle, topicRelationshipStatus);
            string countKey  = this.GetCountKey(appHandle, topicRelationshipStatus);

            Transaction transaction = new Transaction();

            UserRelationshipFeedEntity relationshipFeedEntity = new UserRelationshipFeedEntity()
            {
                RelationshipHandle = relationshipHandle,
                UserHandle         = relationshipUserHandle
            };

            if (readTopicRelationshipLookupEntity == null)
            {
                // if readTopicRelationshipLookupEntity is null, then we are inserting a new relationship
                TopicRelationshipLookupEntity newRelationshipLookupEntity = new TopicRelationshipLookupEntity()
                {
                    RelationshipHandle      = relationshipHandle,
                    LastUpdatedTime         = lastUpdatedTime,
                    TopicRelationshipStatus = topicRelationshipStatus,
                };

                transaction.Add(Operation.Insert(lookupTable, topicHandle, objectKey, newRelationshipLookupEntity));

                if (topicRelationshipStatus != TopicRelationshipStatus.None)
                {
                    transaction.Add(Operation.Insert(feedTable, topicHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                    transaction.Add(Operation.InsertOrIncrement(countTable, topicHandle, countKey));
                }
            }
            else
            {
                // otherwise, we are updating an existing relationship
                TopicRelationshipStatus oldTopicRelationshipStatus = readTopicRelationshipLookupEntity.TopicRelationshipStatus;
                string oldRelationshipHandle = readTopicRelationshipLookupEntity.RelationshipHandle;
                string oldFeedKey            = this.GetFeedKey(appHandle, oldTopicRelationshipStatus);
                string oldCountKey           = this.GetCountKey(appHandle, oldTopicRelationshipStatus);

                readTopicRelationshipLookupEntity.RelationshipHandle      = relationshipHandle;
                readTopicRelationshipLookupEntity.TopicRelationshipStatus = topicRelationshipStatus;
                readTopicRelationshipLookupEntity.LastUpdatedTime         = lastUpdatedTime;

                transaction.Add(Operation.Replace(lookupTable, topicHandle, objectKey, readTopicRelationshipLookupEntity as TopicRelationshipLookupEntity));

                if (topicRelationshipStatus == oldTopicRelationshipStatus)
                {
                    if (topicRelationshipStatus != TopicRelationshipStatus.None && relationshipHandle != oldRelationshipHandle)
                    {
                        transaction.Add(Operation.Delete(feedTable, topicHandle, oldFeedKey, oldRelationshipHandle));
                        transaction.Add(Operation.Insert(feedTable, topicHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                    }
                }
                else
                {
                    if (topicRelationshipStatus != TopicRelationshipStatus.None)
                    {
                        transaction.Add(Operation.Insert(feedTable, topicHandle, feedKey, relationshipHandle, relationshipFeedEntity));
                        transaction.Add(Operation.Increment(countTable, topicHandle, countKey));
                    }

                    if (oldTopicRelationshipStatus != TopicRelationshipStatus.None)
                    {
                        transaction.Add(Operation.Delete(feedTable, topicHandle, oldFeedKey, oldRelationshipHandle));
                        transaction.Add(Operation.Increment(countTable, topicHandle, oldCountKey, -1.0));
                    }
                }
            }

            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #18
0
        /// <summary>
        /// Insert app
        /// </summary>
        /// <param name="storageConsistencyMode">Storage consistency mode</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="developerId">Developer id</param>
        /// <param name="name">App name</param>
        /// <param name="iconHandle">Icon handle</param>
        /// <param name="platformType">Platform type</param>
        /// <param name="deepLink">Deep link</param>
        /// <param name="storeLink">Store link</param>
        /// <param name="createdTime">Created time</param>
        /// <param name="disableHandleValidation">whether to disable validation of app-provided handles</param>
        /// <returns>Create app task</returns>
        public async Task InsertApp(
            StorageConsistencyMode storageConsistencyMode,
            string appHandle,
            string developerId,
            string name,
            string iconHandle,
            PlatformType platformType,
            string deepLink,
            string storeLink,
            DateTime createdTime,
            bool disableHandleValidation)
        {
            AppProfileEntity appProfileEntity = new AppProfileEntity()
            {
                DeveloperId             = developerId,
                Name                    = name,
                IconHandle              = iconHandle,
                PlatformType            = platformType,
                DeepLink                = deepLink,
                StoreLink               = storeLink,
                CreatedTime             = createdTime,
                LastUpdatedTime         = createdTime,
                AppStatus               = AppStatus.Active,
                DisableHandleValidation = disableHandleValidation,
            };

            IdentityProviderCredentialsEntity facebookCredentialsEntity  = new IdentityProviderCredentialsEntity();
            IdentityProviderCredentialsEntity microsoftCredentialsEntity = new IdentityProviderCredentialsEntity();
            IdentityProviderCredentialsEntity googleCredentialsEntity    = new IdentityProviderCredentialsEntity();
            IdentityProviderCredentialsEntity twitterCredentialsEntity   = new IdentityProviderCredentialsEntity();
            IdentityProviderCredentialsEntity aadCredentialsEntity       = new IdentityProviderCredentialsEntity();

            ValidationConfigurationEntity validationConfigurationEntity = new ValidationConfigurationEntity()
            {
                Enabled = false
            };

            PushNotificationsConfigurationEntity windowsPushNotificationsConfigurationEntity = new PushNotificationsConfigurationEntity()
            {
                Enabled = false
            };

            PushNotificationsConfigurationEntity androidPushNotificationsConfigurationEntity = new PushNotificationsConfigurationEntity()
            {
                Enabled = false
            };

            PushNotificationsConfigurationEntity iosPushNotificationsConfigurationEntity = new PushNotificationsConfigurationEntity()
            {
                Enabled = false
            };

            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Apps);

            ObjectTable profilesTable          = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppProfilesObject) as ObjectTable;
            ObjectTable credentialsTable       = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppIdentityProviderCredentialsObject) as ObjectTable;
            ObjectTable validationConfigsTable = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppValidationConfigurationsObject) as ObjectTable;
            ObjectTable pushConfigsTable       = this.tableStoreManager.GetTable(ContainerIdentifier.Apps, TableIdentifier.AppPushNotificationsConfigurationsObject) as ObjectTable;
            Transaction transaction            = new Transaction();

            transaction.Add(Operation.Insert(profilesTable, appHandle, appHandle, appProfileEntity));
            transaction.Add(Operation.Insert(credentialsTable, appHandle, IdentityProviderType.Facebook.ToString(), facebookCredentialsEntity));
            transaction.Add(Operation.Insert(credentialsTable, appHandle, IdentityProviderType.Microsoft.ToString(), microsoftCredentialsEntity));
            transaction.Add(Operation.Insert(credentialsTable, appHandle, IdentityProviderType.Google.ToString(), googleCredentialsEntity));
            transaction.Add(Operation.Insert(credentialsTable, appHandle, IdentityProviderType.Twitter.ToString(), twitterCredentialsEntity));
            transaction.Add(Operation.Insert(credentialsTable, appHandle, IdentityProviderType.AADS2S.ToString(), aadCredentialsEntity));
            transaction.Add(Operation.Insert(validationConfigsTable, appHandle, appHandle, validationConfigurationEntity));
            transaction.Add(Operation.Insert(pushConfigsTable, appHandle, PlatformType.Windows.ToString(), windowsPushNotificationsConfigurationEntity));
            transaction.Add(Operation.Insert(pushConfigsTable, appHandle, PlatformType.Android.ToString(), androidPushNotificationsConfigurationEntity));
            transaction.Add(Operation.Insert(pushConfigsTable, appHandle, PlatformType.IOS.ToString(), iosPushNotificationsConfigurationEntity));
            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }
コード例 #19
0
        /// <summary>
        /// Update pin
        /// </summary>
        /// <param name="storageConsistencyMode">Consistency mode</param>
        /// <param name="pinHandle">Pin handle</param>
        /// <param name="userHandle">User handle</param>
        /// <param name="appHandle">App handle</param>
        /// <param name="topicHandle">Topic handle</param>
        /// <param name="topicUserHandle">User handle of the topic owner</param>
        /// <param name="pinned">Pin status</param>
        /// <param name="lastUpdatedTime">Last updated time</param>
        /// <param name="readPinLookupEntity">Read pin lookup entity</param>
        /// <returns>Update pin task</returns>
        public async Task UpdatePin(
            StorageConsistencyMode storageConsistencyMode,
            string pinHandle,
            string userHandle,
            string appHandle,
            string topicHandle,
            string topicUserHandle,
            bool pinned,
            DateTime lastUpdatedTime,
            IPinLookupEntity readPinLookupEntity)
        {
            CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.Pins);

            ObjectTable lookupTable = this.tableStoreManager.GetTable(ContainerIdentifier.Pins, TableIdentifier.PinsLookup) as ObjectTable;
            FeedTable   feedTable   = this.tableStoreManager.GetTable(ContainerIdentifier.Pins, TableIdentifier.PinsFeed) as FeedTable;
            CountTable  countTable  = this.tableStoreManager.GetTable(ContainerIdentifier.Pins, TableIdentifier.PinsCount) as CountTable;
            Transaction transaction = new Transaction();

            PinFeedEntity pinFeedEntity = new PinFeedEntity()
            {
                PinHandle       = pinHandle,
                TopicHandle     = topicHandle,
                TopicUserHandle = topicUserHandle,
                AppHandle       = appHandle
            };

            if (readPinLookupEntity == null)
            {
                PinLookupEntity newPinLookupEntity = new PinLookupEntity()
                {
                    PinHandle       = pinHandle,
                    LastUpdatedTime = lastUpdatedTime,
                    Pinned          = pinned
                };

                transaction.Add(Operation.Insert(lookupTable, userHandle, topicHandle, newPinLookupEntity));

                if (pinned)
                {
                    transaction.Add(Operation.Insert(feedTable, userHandle, appHandle, pinHandle, pinFeedEntity));
                    transaction.Add(Operation.Insert(feedTable, userHandle, MasterApp.AppHandle, pinHandle, pinFeedEntity));
                    transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, appHandle));
                    transaction.Add(Operation.InsertOrIncrement(countTable, userHandle, MasterApp.AppHandle));
                }
            }
            else
            {
                bool   oldPinned    = readPinLookupEntity.Pinned;
                string oldPinHandle = readPinLookupEntity.PinHandle;

                readPinLookupEntity.PinHandle       = pinHandle;
                readPinLookupEntity.Pinned          = pinned;
                readPinLookupEntity.LastUpdatedTime = lastUpdatedTime;

                transaction.Add(Operation.Replace(lookupTable, userHandle, topicHandle, readPinLookupEntity as PinLookupEntity));

                if (pinned == oldPinned)
                {
                    if (pinned && pinHandle != oldPinHandle)
                    {
                        transaction.Add(Operation.Delete(feedTable, userHandle, appHandle, oldPinHandle));
                        transaction.Add(Operation.Delete(feedTable, userHandle, MasterApp.AppHandle, oldPinHandle));
                        transaction.Add(Operation.Insert(feedTable, userHandle, appHandle, pinHandle, pinFeedEntity));
                        transaction.Add(Operation.Insert(feedTable, userHandle, MasterApp.AppHandle, pinHandle, pinFeedEntity));
                    }
                }
                else
                {
                    if (pinned)
                    {
                        transaction.Add(Operation.Insert(feedTable, userHandle, appHandle, pinHandle, pinFeedEntity));
                        transaction.Add(Operation.Insert(feedTable, userHandle, MasterApp.AppHandle, pinHandle, pinFeedEntity));
                        transaction.Add(Operation.Increment(countTable, userHandle, appHandle, 1));
                        transaction.Add(Operation.Increment(countTable, userHandle, MasterApp.AppHandle, 1));
                    }
                    else
                    {
                        transaction.Add(Operation.Delete(feedTable, userHandle, appHandle, oldPinHandle));
                        transaction.Add(Operation.Delete(feedTable, userHandle, MasterApp.AppHandle, oldPinHandle));
                        transaction.Add(Operation.Increment(countTable, userHandle, appHandle, -1.0));
                        transaction.Add(Operation.Increment(countTable, userHandle, MasterApp.AppHandle, -1.0));
                    }
                }
            }

            await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode());
        }