From 24544b4451272abb79fa1bdf3300ae307b9c5df5 Mon Sep 17 00:00:00 2001 From: Mateusz Wiktor Date: Wed, 9 Sep 2026 08:05:37 +0200 Subject: [PATCH 1/2] Add DataSync docs snippets Co-Authored-By: Claude Opus 5 (1M context) --- .../DataSync/DataSyncSample.cs | 872 ++++++++++++++++++ .../PubnubApi.Snippets.csproj | 1 + 2 files changed, 873 insertions(+) create mode 100644 src/PubnubApi.Snippets/DataSync/DataSyncSample.cs diff --git a/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs b/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs new file mode 100644 index 000000000..7aeb061e9 --- /dev/null +++ b/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs @@ -0,0 +1,872 @@ +// snippet.using +using PubnubApi; +using PubnubApi.EndPoint; + +// snippet.end + +public class DataSyncSample +{ + private static Pubnub pubnub; + + static void Init() + { + // snippet.pubnub_init + // Configuration + PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId")) + { + SubscribeKey = "demo", + PublishKey = "demo", + Secure = true + }; + + // Initialize PubNub + Pubnub pubnub = new Pubnub(pnConfiguration); + + // snippet.end + } + + // Users + + public static async Task CreateUserBasicUsage() + { + // snippet.create_user_basic_usage + try + { + PNResult response = await pubnub.DataSync.CreateUser(new CreateUserParameters + { + Id = "user-alice", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Alice" }, + { "type", "shopper" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetUserBasicUsage() + { + // snippet.get_user_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetUser(new GetUserParameters + { + Id = "user-alice", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetUsersBasicUsage() + { + // snippet.get_users_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetUsers(new GetUsersParameters + { + Limit = 20, + Sort = "createdAt", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task SetUserBasicUsage() + { + // snippet.set_user_basic_usage + try + { + PNResult response = await pubnub.DataSync.SetUser(new SetUserParameters + { + Id = "user-alice", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Alice B." }, + { "type", "shopper" }, + }, + IfMatch = "AbQdEfGhIjKlMn", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateUserBasicUsage() + { + // snippet.update_user_basic_usage + try + { + PNResult response = await pubnub.DataSync.UpdateUser(new UpdateUserParameters + { + Id = "user-alice", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/name", Value = "Alice B." }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task RemoveUserBasicUsage() + { + // snippet.remove_user_basic_usage + try + { + PNResult response = await pubnub.DataSync.DeleteUser(new DeleteUserParameters + { + Id = "user-alice", + }); + + Console.WriteLine(response.Status.StatusCode); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Channels + + public static async Task CreateChannelBasicUsage() + { + // snippet.create_channel_basic_usage + try + { + PNResult response = await pubnub.DataSync.CreateChannel(new CreateChannelParameters + { + Id = "channel-summer-sale", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Summer Sale" }, + { "type", "promotion" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetChannelBasicUsage() + { + // snippet.get_channel_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetChannel(new GetChannelParameters + { + Id = "channel-summer-sale", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetChannelsBasicUsage() + { + // snippet.get_channels_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetChannels(new GetChannelsParameters + { + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task SetChannelBasicUsage() + { + // snippet.set_channel_basic_usage + try + { + PNResult response = await pubnub.DataSync.SetChannel(new SetChannelParameters + { + Id = "channel-summer-sale", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Summer Sale 2026" }, + { "type", "promotion" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateChannelBasicUsage() + { + // snippet.update_channel_basic_usage + try + { + PNResult response = await pubnub.DataSync.UpdateChannel(new UpdateChannelParameters + { + Id = "channel-summer-sale", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/name", Value = "Summer Sale 2026" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task RemoveChannelBasicUsage() + { + // snippet.remove_channel_basic_usage + try + { + PNResult response = await pubnub.DataSync.DeleteChannel(new DeleteChannelParameters + { + Id = "channel-summer-sale", + }); + + Console.WriteLine(response.Status.StatusCode); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Memberships + + public static async Task CreateMembershipBasicUsage() + { + // snippet.create_membership_basic_usage + try + { + PNResult response = await pubnub.DataSync.CreateMembership(new CreateMembershipParameters + { + ChannelId = "channel-summer-sale", + UserId = "user-alice", + MembershipClassVersion = 1, + Payload = new Dictionary + { + { "role", "viewer" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetMembershipBasicUsage() + { + // snippet.get_membership_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetMembership(new GetMembershipParameters + { + Id = "membership-alice-summer-sale", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetMembershipsBasicUsage() + { + // snippet.get_memberships_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetMemberships(new GetMembershipsParameters + { + UserId = "user-alice", + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task SetMembershipBasicUsage() + { + // snippet.set_membership_basic_usage + try + { + PNResult response = await pubnub.DataSync.SetMembership(new UpdateMembershipParameters + { + Id = "membership-alice-summer-sale", + RelationshipClassVersion = 1, + Payload = new Dictionary + { + { "role", "moderator" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateMembershipBasicUsage() + { + // snippet.update_membership_basic_usage + try + { + PNResult response = await pubnub.DataSync.UpdateMembership(new PatchMembershipParameters + { + Id = "membership-alice-summer-sale", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/role", Value = "moderator" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task RemoveMembershipBasicUsage() + { + // snippet.remove_membership_basic_usage + try + { + PNResult response = await pubnub.DataSync.DeleteMembership(new DeleteMembershipParameters + { + Id = "membership-alice-summer-sale", + }); + + Console.WriteLine(response.Status.StatusCode); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Entities + + public static async Task CreateEntityBasicUsage() + { + // snippet.create_entity_basic_usage + try + { + PNResult response = await pubnub.DataSync.CreateEntity(new CreateEntityParameters + { + Id = "product-sneaker-42", + EntityClass = "product", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Retro Sneaker" }, + { "price", 89.99 }, + { "stock", 12 }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetEntityBasicUsage() + { + // snippet.get_entity_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetEntity(new GetEntityParameters + { + Id = "product-sneaker-42", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetEntitiesBasicUsage() + { + // snippet.get_entities_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetEntities(new GetEntitiesParameters + { + EntityClass = "product", + Sort = "price:desc", + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task SetEntityBasicUsage() + { + // snippet.set_entity_basic_usage + try + { + PNResult response = await pubnub.DataSync.SetEntity(new SetEntityParameters + { + Id = "product-sneaker-42", + EntityClassVersion = 1, + Payload = new Dictionary + { + { "name", "Retro Sneaker" }, + { "price", 79.99 }, + { "stock", 8 }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateEntityBasicUsage() + { + // snippet.update_entity_basic_usage + try + { + PNResult response = await pubnub.DataSync.UpdateEntity(new UpdateEntityParameters + { + Id = "product-sneaker-42", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/price", Value = 79.99 }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task RemoveEntityBasicUsage() + { + // snippet.remove_entity_basic_usage + try + { + PNResult response = await pubnub.DataSync.DeleteEntity(new DeleteEntityParameters + { + Id = "product-sneaker-42", + }); + + Console.WriteLine(response.Status.StatusCode); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Relationships + + public static async Task CreateRelationshipBasicUsage() + { + // snippet.create_relationship_basic_usage + try + { + PNResult response = await pubnub.DataSync.CreateRelationship(new CreateRelationshipParameters + { + EntityAId = "seller-bob", + EntityBId = "product-sneaker-42", + RelationshipClass = "ProductOwner", + RelationshipClassVersion = 1, + Payload = new Dictionary + { + { "since", "2026-07-13" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetRelationshipBasicUsage() + { + // snippet.get_relationship_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetRelationship(new GetRelationshipParameters + { + Id = "rel-bob-owns-sneaker-42", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetRelationshipsBasicUsage() + { + // snippet.get_relationships_basic_usage + try + { + PNResult response = await pubnub.DataSync.GetRelationships(new GetRelationshipsParameters + { + RelationshipClass = "ProductOwner", + EntityAId = "seller-bob", + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task SetRelationshipBasicUsage() + { + // snippet.set_relationship_basic_usage + try + { + PNResult response = await pubnub.DataSync.SetRelationship(new SetRelationshipParameters + { + Id = "rel-bob-owns-sneaker-42", + RelationshipClassVersion = 1, + Payload = new Dictionary + { + { "since", "2026-07-13" }, + { "tier", "gold" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateRelationshipBasicUsage() + { + // snippet.update_relationship_basic_usage + try + { + PNResult response = await pubnub.DataSync.UpdateRelationship(new UpdateRelationshipParameters + { + Id = "rel-bob-owns-sneaker-42", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/tier", Value = "platinum" }, + }, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task RemoveRelationshipBasicUsage() + { + // snippet.remove_relationship_basic_usage + try + { + PNResult response = await pubnub.DataSync.DeleteRelationship(new DeleteRelationshipParameters + { + Id = "rel-bob-owns-sneaker-42", + }); + + Console.WriteLine(response.Status.StatusCode); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } +} diff --git a/src/PubnubApi.Snippets/PubnubApi.Snippets.csproj b/src/PubnubApi.Snippets/PubnubApi.Snippets.csproj index 1b2dbafff..07491c63e 100644 --- a/src/PubnubApi.Snippets/PubnubApi.Snippets.csproj +++ b/src/PubnubApi.Snippets/PubnubApi.Snippets.csproj @@ -11,6 +11,7 @@ + From eecc069d1f05ed8aa71a9018e3e40c6697bd6507 Mon Sep 17 00:00:00 2001 From: Mateusz Wiktor Date: Wed, 9 Sep 2026 08:27:00 +0200 Subject: [PATCH 2/2] Add remaining DataSync docs snippets (filters, pagination, listeners, grants) Co-Authored-By: Claude Opus 5 (1M context) --- .../AccessManager/AccessManagerSample.cs | 90 ++- .../DataSync/DataSyncSample.cs | 594 ++++++++++++++++++ .../Publish/PublishSubscribeSample.cs | 120 ++++ 3 files changed, 803 insertions(+), 1 deletion(-) diff --git a/src/PubnubApi.Snippets/AccessManager/AccessManagerSample.cs b/src/PubnubApi.Snippets/AccessManager/AccessManagerSample.cs index 56bcf4abd..da4da15fa 100644 --- a/src/PubnubApi.Snippets/AccessManager/AccessManagerSample.cs +++ b/src/PubnubApi.Snippets/AccessManager/AccessManagerSample.cs @@ -155,7 +155,95 @@ static async Task GrantTokenComplexWithRegex() } // snippet.end } - + + static async Task GrantTokenDataSync() + { + // snippet.grant_token_datasync + try + { + PNResult grantResponse = await pubnub.GrantToken() + .TTL(15) + .AuthorizedUuid("user-alice") + .Resources(new PNTokenResources + { + DataSync = new PNDataSyncTokenScopes + { + Entities = new Dictionary + { + { "product-sneaker-42", new PNTokenAuthValues { Get = true } }, + }, + }, + }) + .Patterns(new PNTokenPatterns + { + DataSync = new PNDataSyncTokenScopes + { + Entities = new Dictionary + { + { "product-.*", new PNTokenAuthValues { Get = true } }, + }, + }, + }) + .ExecuteAsync(); + + Console.WriteLine(grantResponse.Result.Token); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + static async Task GrantTokenDataSyncProjection() + { + // snippet.grant_token_datasync_projection + try + { + PNResult grantResponse = await pubnub.GrantToken() + .TTL(15) + .AuthorizedUuid("user-alice") + .Resources(new PNTokenResources + { + DataSync = new PNDataSyncTokenScopes + { + Entities = new Dictionary + { + { "product-sneaker-42", new PNTokenAuthValues { Get = true } }, + }, + }, + }) + .Patterns(new PNTokenPatterns + { + DataSync = new PNDataSyncTokenScopes + { + Entities = new Dictionary + { + { "product-.*", new PNTokenAuthValues { Get = true } }, + }, + }, + }) + .DataSyncProjections(new PNDataSyncProjections + { + Resources = new PNDataSyncProjectionScope + { + Entities = new Dictionary + { + { "product-sneaker-42", "public" }, + }, + }, + }) + .ExecuteAsync(); + + Console.WriteLine(grantResponse.Result.Token); + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + static async Task GrantTokenOldBasicUsage() { // snippet.basic_usage_old diff --git a/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs b/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs index 7aeb061e9..33412eb91 100644 --- a/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs +++ b/src/PubnubApi.Snippets/DataSync/DataSyncSample.cs @@ -869,4 +869,598 @@ public static async Task RemoveRelationshipBasicUsage() } // snippet.end } + + // Users - other examples + + public static async Task GetUsersFilterFast() + { + // snippet.get_users_filter_fast + try + { + PNResult response = await pubnub.DataSync.GetUsers(new GetUsersParameters + { + FilterFast = "type == \"shopper\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetUsersFilter() + { + // snippet.get_users_filter + try + { + PNResult response = await pubnub.DataSync.GetUsers(new GetUsersParameters + { + Filter = "name LIKE \"*Alice*\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetUsersPagination() + { + // snippet.get_users_pagination + try + { + string cursor = null; + bool hasNext = true; + int page = 0; + + while (hasNext) + { + PNResult response = await pubnub.DataSync.GetUsers(new GetUsersParameters + { + FilterFast = "type == \"shopper\"", + Limit = 20, + Cursor = cursor, + }); + + if (!response.Status.Error) + { + Console.WriteLine($"Page {++page}: {response.Result.Data.Count}"); + cursor = response.Result.Meta.NextCursor; + hasNext = response.Result.Meta.HasNext; + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + hasNext = false; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Channels - other examples + + public static async Task GetChannelsFilterFast() + { + // snippet.get_channels_filter_fast + try + { + PNResult response = await pubnub.DataSync.GetChannels(new GetChannelsParameters + { + FilterFast = "type == \"promotion\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetChannelsFilter() + { + // snippet.get_channels_filter + try + { + PNResult response = await pubnub.DataSync.GetChannels(new GetChannelsParameters + { + Filter = "name LIKE \"*Sale*\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetChannelsPagination() + { + // snippet.get_channels_pagination + try + { + string cursor = null; + bool hasNext = true; + int page = 0; + + while (hasNext) + { + PNResult response = await pubnub.DataSync.GetChannels(new GetChannelsParameters + { + FilterFast = "type == \"promotion\"", + Limit = 20, + Cursor = cursor, + }); + + if (!response.Status.Error) + { + Console.WriteLine($"Page {++page}: {response.Result.Data.Count}"); + cursor = response.Result.Meta.NextCursor; + hasNext = response.Result.Meta.HasNext; + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + hasNext = false; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Memberships - other examples + + public static async Task GetMembershipsByChannelId() + { + // snippet.get_memberships_by_channel_id + try + { + PNResult response = await pubnub.DataSync.GetMemberships(new GetMembershipsParameters + { + ChannelId = "channel-summer-sale", + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetMembershipsFilterFast() + { + // snippet.get_memberships_filter_fast + try + { + PNResult response = await pubnub.DataSync.GetMemberships(new GetMembershipsParameters + { + UserId = "user-alice", + FilterFast = "role == \"viewer\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetMembershipsFilter() + { + // snippet.get_memberships_filter + try + { + PNResult response = await pubnub.DataSync.GetMemberships(new GetMembershipsParameters + { + ChannelId = "channel-summer-sale", + Filter = "role LIKE \"*mod*\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetMembershipsPagination() + { + // snippet.get_memberships_pagination + try + { + string cursor = null; + bool hasNext = true; + int page = 0; + + while (hasNext) + { + PNResult response = await pubnub.DataSync.GetMemberships(new GetMembershipsParameters + { + UserId = "user-alice", + Limit = 20, + Cursor = cursor, + }); + + if (!response.Status.Error) + { + Console.WriteLine($"Page {++page}: {response.Result.Data.Count}"); + cursor = response.Result.Meta.NextCursor; + hasNext = response.Result.Meta.HasNext; + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + hasNext = false; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Entities - other examples + + public static async Task GetEntitiesFilterFast() + { + // snippet.get_entities_filter_fast + try + { + PNResult response = await pubnub.DataSync.GetEntities(new GetEntitiesParameters + { + EntityClass = "product", + FilterFast = "price < 100 && stock > 0", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetEntitiesFilter() + { + // snippet.get_entities_filter + try + { + PNResult response = await pubnub.DataSync.GetEntities(new GetEntitiesParameters + { + EntityClass = "product", + Filter = "name LIKE \"*sneaker*\" && !(status == \"discontinued\")", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetEntitiesPagination() + { + // snippet.get_entities_pagination + try + { + string cursor = null; + bool hasNext = true; + int page = 0; + + while (hasNext) + { + PNResult response = await pubnub.DataSync.GetEntities(new GetEntitiesParameters + { + EntityClass = "product", + FilterFast = "price < 100", + Limit = 20, + Cursor = cursor, + }); + + if (!response.Status.Error) + { + Console.WriteLine($"Page {++page}: {response.Result.Data.Count}"); + cursor = response.Result.Meta.NextCursor; + hasNext = response.Result.Meta.HasNext; + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + hasNext = false; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task UpdateEntityMultipleOperations() + { + // snippet.update_entity_multiple_operations + try + { + PNResult response = await pubnub.DataSync.UpdateEntity(new UpdateEntityParameters + { + Id = "product-sneaker-42", + Operations = new List + { + new JsonPatchOperation { Op = JsonPatchOperationType.Test, Path = "/payload/stock", Value = 8 }, + new JsonPatchOperation { Op = JsonPatchOperationType.Replace, Path = "/payload/price", Value = 74.99 }, + new JsonPatchOperation { Op = JsonPatchOperationType.Add, Path = "/payload/tags/-", Value = "clearance" }, + new JsonPatchOperation { Op = JsonPatchOperationType.Remove, Path = "/payload/legacy/field" }, + new JsonPatchOperation { Op = JsonPatchOperationType.Move, Path = "/payload/displayName", From = "/payload/legacyName" }, + new JsonPatchOperation { Op = JsonPatchOperationType.Copy, Path = "/payload/previousName", From = "/payload/displayName" }, + }, + IfMatch = "StUvWxYzAbCdEf", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Id); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Relationships - other examples + + public static async Task GetRelationshipsByEntityBId() + { + // snippet.get_relationships_by_entity_b_id + try + { + PNResult response = await pubnub.DataSync.GetRelationships(new GetRelationshipsParameters + { + RelationshipClass = "ProductOwner", + EntityBId = "product-sneaker-42", + Limit = 20, + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetRelationshipsFilterFast() + { + // snippet.get_relationships_filter_fast + try + { + PNResult response = await pubnub.DataSync.GetRelationships(new GetRelationshipsParameters + { + RelationshipClass = "ProductOwner", + FilterFast = "tier == \"gold\"", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetRelationshipsFilter() + { + // snippet.get_relationships_filter + try + { + PNResult response = await pubnub.DataSync.GetRelationships(new GetRelationshipsParameters + { + RelationshipClass = "ProductOwner", + Filter = "!(tier == \"platinum\")", + }); + + if (!response.Status.Error) + { + Console.WriteLine(response.Result.Data.Count); + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + public static async Task GetRelationshipsPagination() + { + // snippet.get_relationships_pagination + try + { + string cursor = null; + bool hasNext = true; + int page = 0; + + while (hasNext) + { + PNResult response = await pubnub.DataSync.GetRelationships(new GetRelationshipsParameters + { + RelationshipClass = "ProductOwner", + EntityAId = "seller-bob", + Limit = 20, + Cursor = cursor, + }); + + if (!response.Status.Error) + { + Console.WriteLine($"Page {++page}: {response.Result.Data.Count}"); + cursor = response.Result.Meta.NextCursor; + hasNext = response.Result.Meta.HasNext; + } + else + { + Console.WriteLine($"Request can't be executed due to error: {response.Status.ErrorData.Information}"); + hasNext = false; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Request can't be executed due to error: {ex.Message}"); + } + // snippet.end + } + + // Real-time updates + + public static async Task DataSyncEventListener() + { + // snippet.data_sync_event_listener + Channel channel = pubnub.Channel("product-sneaker-42"); + Subscription subscription = channel.Subscription(); + + subscription.AddListener(new SubscribeCallbackExt( + (Pubnub pn, PNDataSyncEventResult dataSyncEvent) => + { + string changedId = dataSyncEvent.EntityData?.Id + ?? dataSyncEvent.RelationshipData?.Id + ?? dataSyncEvent.Id; + Console.WriteLine($"{dataSyncEvent.Event} {changedId}"); + }, + (Pubnub pn, PNStatus status) => { })); + + subscription.Subscribe(); + // snippet.end + } + + // Projection channels + + public static async Task SubscribeToProjectionChannels() + { + // snippet.subscribe_to_projection_channels + // Base projection: the __default__ view of the payload. + Subscription baseSubscription = pubnub.Channel("product-sneaker-42").Subscription(); + + // admin projection: the admin view of the payload. + Subscription adminSubscription = pubnub.Channel("__admin__product-sneaker-42").Subscription(); + // snippet.end + } } diff --git a/src/PubnubApi.Snippets/Publish/PublishSubscribeSample.cs b/src/PubnubApi.Snippets/Publish/PublishSubscribeSample.cs index 0c7a1ea8a..d37e7bab0 100644 --- a/src/PubnubApi.Snippets/Publish/PublishSubscribeSample.cs +++ b/src/PubnubApi.Snippets/Publish/PublishSubscribeSample.cs @@ -1,5 +1,6 @@ // snippet.using using PubnubApi; +using PubnubApi.EndPoint; // snippet.end @@ -891,6 +892,125 @@ public static void AddConnectionStatusListener() // snippet.end } + public static async Task AddDataSyncListener() + { + // snippet.add_datasync_listener + // Using SubscribeCallbackExt + Subscription subscription = pubnub.Channel("product-sneaker-42").Subscription(); + + var listener = new SubscribeCallbackExt( + (Pubnub pn, PNDataSyncEventResult dataSyncEvent) => { /* handle event */ }, + (Pubnub pn, PNStatus status) => { /* handle status */ }); + + subscription.AddListener(listener); + // snippet.end + } + + public static async Task HandleDataSyncEvent() + { + // snippet.handle_datasync_event + // Subscribe to the object's id channel and attach the listener + const string objectId = "product-sneaker-42"; + Channel channel = pubnub.Channel(objectId); + Subscription subscription = channel.Subscription(); + + var listener = new SubscribeCallbackExt( + (Pubnub pn, PNDataSyncEventResult dataSyncEvent) => + { + // This channel can also receive relationship events and events about + // connected entities. Only handle events for the observed product. + string changedId = dataSyncEvent.Event == "delete" + ? dataSyncEvent.Id + : dataSyncEvent.EntityData?.Id; + + if (dataSyncEvent.Type != "entity" || changedId != objectId) + { + return; + } + + switch (dataSyncEvent.Event) + { + case "create": + Console.WriteLine("Product created: " + changedId); + break; + case "update": + Dictionary payload = dataSyncEvent.EntityData?.Payload; + if (payload != null && payload.TryGetValue("price", out object price)) + { + Console.WriteLine("New price: " + price); + } + break; + case "delete": + Console.WriteLine("Product deleted: " + changedId); + break; + } + }, + (Pubnub pn, PNStatus status) => { /* handle status */ }); + + subscription.AddListener(listener); + subscription.Subscribe(); + // snippet.end + } + + public static void DataSyncLocalCopySync() + { + // snippet.datasync_local_copy_sync + PNDataSyncEntityResult localCopy = null; + + async void RefreshLocalCopy() + { + PNResult response = await pubnub.DataSync.GetEntity(new GetEntityParameters + { + Id = "product-sneaker-42", + }); + + if (!response.Status.Error) + { + localCopy = response.Result; + } + } + + void ApplyEvent(PNDataSyncEventResult dataSyncEvent) + { + const string objectId = "product-sneaker-42"; + + // This channel can also receive relationship events and events about + // connected entities. Only apply events for the fetched entity. + // `Product` is a class of your own, so its events report Type "entity". + // A built-in user, channel, or membership reports "user", "channel", or "membership". + if (dataSyncEvent.Type != "entity") + { + return; + } + + if (dataSyncEvent.Event == "delete") + { + if (dataSyncEvent.Id != objectId) + { + return; + } + + localCopy = null; + return; + } + + PNDataSyncEntityResult changedEntity = dataSyncEvent.EntityData; + if (changedEntity == null || changedEntity.Id != objectId) + { + return; + } + + // Skip events that are older than what you already have. + if (localCopy != null && string.CompareOrdinal(changedEntity.UpdatedAt, localCopy.UpdatedAt) <= 0) + { + return; + } + + localCopy = changedEntity; + } + // snippet.end + } + public static void UnsubscribeNewBasicUsage() { // snippet.unsubscribe_new_basic_usage