From eb1543d420acc637c93e50598628a81ef936f636 Mon Sep 17 00:00:00 2001 From: Xavrax Date: Thu, 25 Jul 2024 15:40:07 +0200 Subject: [PATCH 1/8] add object definitions and docs --- core/pubnub_objects_api.h | 446 +++++++++++++++++++++++++++++++++++++- 1 file changed, 445 insertions(+), 1 deletion(-) diff --git a/core/pubnub_objects_api.h b/core/pubnub_objects_api.h index e487e174..6f288890 100644 --- a/core/pubnub_objects_api.h +++ b/core/pubnub_objects_api.h @@ -11,6 +11,114 @@ #include +/** Data pagination object. This object helps to paginate through the data. + It is more readable form of `start` and `end` parameters in objects API. + */ +struct pubnub_page_object { + /** The URL for the next page of results. If there is no next page, this field is null. */ + char const* next; + + /** The URL for the previous page of results. If there is no previous page, this field is null. */ + char const* prev; +}; + + +/** User data object. This object represents the user data. */ +struct pubnub_user_data { + + /** Name Display name for the user. */ + char const* name; + + /** User's identifier in an external system */ + char const* external_id; + + /** The URL of the user's profile picture */ + char const* profile_url; + + /** The user's email. */ + char const* email; + + /** JSON providing custom data about the user. Values must be scalar only; arrays or objects are not supported. + Filtering App Context data through the custom property is not recommended in SDKs. */ + char const* custom; +}; + + +/** Channel data object. This object represents the channel data. */ +struct pubnub_channel_data { + /** Display name for the channel. */ + char const* name; + + /** The channel's description. */ + char const* description; + + /** JSON providing custom data about the channel. Values must be scalar only; arrays or objects are not supported. + Filtering App Context data through the custom property is not recommended in SDKs. */ + char const* custom; +}; + + +/** The "null" page object, which is used to indicate that there is no next or previous page. + Also it can be used when there is no will to pass page as a parameter + */ +PUBNUB_EXTERN const struct pubnub_page_object pubnub_null_page = { NULL, NULL }; + + +/** The "null" user data object, which is used to indicate that there is no user data. + Also it can be used when there is no will to pass user data as a parameter + */ +PUBNUB_EXTERN const struct pubnub_user_data pubnub_null_user_data = { NULL, NULL, NULL, NULL, NULL }; + + +/** The "null" channel data object, which is used to indicate that there is no channel data. + Also it can be used when there is no will to pass channel data as a parameter + */ +PUBNUB_EXTERN const struct pubnub_channel_data pubnub_null_channel_data = { NULL, NULL, NULL }; + + +/** Options for the getall_*metadata functions */ +struct pubnub_getall_metadata_opts { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; +}; + + +/** Default options for the set_*metadata functions + Values are set as follows: + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + - count: pbNotSet + + @see pubnub_getall_metadata_opts + @see pubnub_null_page + + @return Default options for the set_*metadata functions + */ +PUBNUB_EXTERN struct pubnub_getall_metadata_opts pubnub_getall_metadata_defopts(); + /** Returns a paginated list of metadata objects for users associated with the subscription key of the context @p pbp, optionally including each record's custom data object. @@ -35,6 +143,21 @@ PUBNUB_EXTERN enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* end, enum pubnub_tribool count); + +/** Returns a paginated list of metadata objects for users associated with the subscription key of the context @p pbp, + optionally including each record's custom data object. + + Use `pubnub_getall_metadata_defopts()` to get the default options. + + @see pubnub_getall_metadata_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the getall_uuidmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_getall_uuidmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts); + + /** Creates a metadata for a uuid with the attributes specified in @p uuid_metadata_obj. Returns the created metadata uuid object, optionally including the user's custom data object. @note User ID and name are required properties in the @p uuid_metadata_obj @@ -53,6 +176,47 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, char const* uuid_metadata_obj); +/** Options for the `pubnub_set_uuidmetadata_ex` function */ +struct pubnub_set_uuidmetadata_opts { + /** Uuid of the user. */ + char const* uuid; + + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** The user data object. */ + struct pubnub_user_data data; +}; + +/** Default options for the set_uuidmetadata functions + Values are set as follows: + - uuid: NULL (`pubnub_set_uuidmetadata_ex` will take the user_id from the context on NULL) + - include: NULL + - data: pubnub_null_user_data + + @see pubnub_null_user_data + + @return Default options for the set_uuidmetadata functions + */ +PUBNUB_EXTERN struct pubnub_set_uuidmetadata_opts pubnub_set_uuidmetadata_defopts(); + + +/** Creates a metadata for a uuid with the attributes specified in @p opts. + Returns the created metadata uuid object, optionally including the user's custom data object. + + Use `pubnub_set_uuidmetadata_defopts()` to get the default options. + + @see pubnub_set_uuidmetadata_defopts + + @param pb The pubnub context. Can't be NULL + @param uuid The UUID to create the metadata for. If NULL, the user_id will be taken from the context. + @param opts The options for the set_uuidmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, struct pubnub_set_uuidmetadata_opts opts); + + /** Returns the uuid metadata object specified with @p user_id, optionally including the user's custom data object. @param pb The pubnub context. Can't be NULL @@ -67,7 +231,6 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_uuidmetadata(pubnub_t* pb, char const* uuid_metadataid); - /** Deletes the uuid metadata specified with @p uuid_metadataid. @param pb The pubnub context. Can't be NULL @param uuid_metadataid The UUID Metatdata ID. Cannot be NULL. @@ -100,6 +263,20 @@ PUBNUB_EXTERN enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, enum pubnub_tribool count); +/** Returns the spaces associated with the subscriber key of the context @p pbp, optionally + including each space's custom data object. + + Use `pubnub_getall_metadata_defopts()` to get the default options. + + @see pubnub_getall_metadata_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the getall_channelmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_getall_channelmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts); + + /** Creates a metadata for the specified channel with the attributes specified in @p channel_metadata_obj. Returns the created space object, optionally including its custom data object. @note Channel ID and name are required properties of @p channel_metadata_obj @@ -115,6 +292,44 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, char const* channel_metadata_obj); +/** Options for the `pubnub_set_channelmetadata_ex` function */ +struct pubnub_set_channelmetadata_opts { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** The channel data object. */ + struct pubnub_channel_data data; +}; + + +/** Default options for the set_channelmetadata functions. + Values are set as follows: + - include: NULL + - data: pubnub_null_channel_data + + @see pubnub_null_channel_data + + @return Default options for the set_channelmetadata_ex function. + */ +PUBNUB_EXTERN struct pubnub_set_channelmetadata_opts pubnub_set_channelmetadata_defopts(); + + +/** Creates a metadata for the specified channel with the attributes specified in @p opts. + Returns the created space object, optionally including its custom data object. + + Use `pubnub_set_channelmetadata_defopts()` to get the default options. + + @see pubnub_set_channelmetadata_defopts + + @param pb The pubnub context. Can't be NULL + @param channel The channel to create the metadata for. If NULL, the channel will be taken from the context. + @param opts The options for the set_channelmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, char const* channel, struct pubnub_set_channelmetadata_opts opts); + + /** Returns the channel metadata object specified with @p channel_metadataid, optionally including its custom data object. @param pb The pubnub context. Can't be NULL @@ -137,6 +352,49 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_channelmetadata(pubnub_t* pb, PUBNUB_EXTERN enum pubnub_res pubnub_remove_channelmetadata(pubnub_t* pb, char const* channel_metadataid); +/** Options for the pubnub_get_memberships function */ +struct pubnub_membership_data { + /** The UUID to retrieve the memberships. */ + char const* uuid; + + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; +}; + + +/** Default options for the pubnub_get_memberships function + Values are set as follows: + - uuid: NULL (`pubnub_get_memberships_ex` will take the user_id from the context on NULL) + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + + @see pubnub_null_page + + @return Default options for the get_memberships function + */ +PUBNUB_EXTERN struct pubnub_membership_data pubnub_memberships_defopts(); + + /** Returns the channel memberships of the user specified by @p uuid_metadataid, optionally including the custom data objects for... @param pb The pubnub context. Can't be NULL @@ -165,6 +423,20 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships(pubnub_t* pb, enum pubnub_tribool count); +/** Returns the channel memberships of the user specified by @p uuid_metadataid, optionally including + the custom data objects for... + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the get_memberships function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, struct pubnub_membership_data opts); + + /** Add/Update the channel memberships of the UUID specified by @p metadata_uuid. Uses the `set` property to perform those operations on one, or more memberships. An example for @set_obj: @@ -198,6 +470,37 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships(pubnub_t* pb, char const* set_obj); +/** Add/Update the channel memberships of the UUID specified by @p metadata_uuid. Uses the `set` property + to perform those operations on one, or more memberships. + An example for @channels: + [ + { + "channel":{ "id": "main-channel-id" }, + "custom": { + "starred": true + } + }, + { + "channel":{ "id": "channel-0" }, + "some_key": { + "other_key": "other_value" + } + } + ] + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be NULL + @param channels The JSON object that defines the add/update to perform. + Cannot be NULL. + @param opts The options for the set_memberships function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_data opts); + + /** Removes the memberships of the user specified by @p uuid_metadataid. Uses the `delete` property to perform those operations on one, or more memberships. An example for @remove_obj: @@ -225,6 +528,75 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, char const* remove_obj); +/** Removes the memberships of the user specified by @p uuid_metadataid. Uses the `delete` property + to perform those operations on one, or more memberships. + An example for @channels: + [ + { + "id": "main-channel-id" + }, + { + "id": "channel-0" + } + ] + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be null + @param channels The JSON object that defines the remove to perform. + Cannot be NULL. + @param opts The options for the remove_memberships function. + + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_data opts); + + +/** Options for the pubnub_*_members functions */ +struct pubnub_members_data { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; +}; + + +/** Default options for the pubnub_get_members functions + Values are set as follows: + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + - count: pbNotSet + + @see pubnub_null_page + + @return Default options for the get_members function + */ +PUBNUB_EXTERN struct pubnub_members_data pubnub_get_members_defopts(); + + /** Returns all users in the channel specified with @p channel_metadataid, optionally including the custom data objects for... @param pb The pubnub context. Can't be NULL @@ -252,6 +624,21 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_members(pubnub_t* pb, enum pubnub_tribool count); +/** Returns all users in the channel specified with @p channel_metadataid, optionally including + the custom data objects for... + + Use `pubnub_get_members_defopts()` to get the default options. + + @see pubnub_get_members_defopts + + @param pb The pubnub context. Can't be NULL + @param channel The channel to retrieve the members for. + @param opts The options for the get_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, char const* channel, struct pubnub_members_data opts); + + /** Adds the list of members of the channel specified with @p channel_metadataid. Uses the `add` property to perform the operation on one or more members. An example for @add_obj: @@ -308,6 +695,36 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_members(pubnub_t* pb, char const* set_obj); +/** Updates the list of members of the space specified with @p space_id. Uses the `update` + property to perform the operation on one or more members. + An example for @uuids: + [ + { + "id": "some-user-id", + "custom": { + "starred": true + } + }, + { + "id": "user-0-id", + "some_key": { + "other_key": "other_value" + } + } + ] + + @param pb The pubnub context. Can't be NULL + @param channel The channel to add/update the members. + @param uuids The JSON object that defines the add/update to perform. Cannot be NULL. + @param opts The options for the set_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_data opts); + + /** Removes the list of members of the space specified with @p space_id. Uses the `remove` property to perform the operation on one or more members. An example for @update_obj: @@ -336,6 +753,33 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_members(pubnub_t* pb, char const* remove_obj); +/** Removes the list of members of the space specified with @p space_id. Uses the `remove` + property to perform the operation on one or more members. + An example for @uuids: + [ + { + "id": "some-user-id", + "custom": { + "starred": true + } + }, + { + "id": "user-0-id" + } + ] + + @param pb The pubnub context. Can't be NULL + @param channel The channel to remove the members. + @param uuids The JSON object that defines the remove to perform. Cannot be NULL. + @param opts The options for the remove_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_remove_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_data opts); + + #endif /* !defined INC_PUBNUB_OBJECTS_API */ #endif /* PUBNUB_USE_OBJECTS_API */ From dd87160f450d6e1b8c34448831697555eac7b55e Mon Sep 17 00:00:00 2001 From: Xavrax Date: Mon, 29 Jul 2024 03:17:52 +0200 Subject: [PATCH 2/8] I had to remove commits and commit them back because of the keyset --- core/pbcc_objects_api.c | 54 +++ core/pbcc_objects_api.h | 22 + core/pubnub_objects_api.c | 394 ++++++++++++++++-- core/pubnub_objects_api.h | 34 +- core/samples/pubnub_objects_api_sample.c | 502 +++++++++++++++++++++++ 5 files changed, 951 insertions(+), 55 deletions(-) create mode 100644 core/samples/pubnub_objects_api_sample.c diff --git a/core/pbcc_objects_api.c b/core/pbcc_objects_api.c index 68f64c31..c81d61b4 100644 --- a/core/pbcc_objects_api.c +++ b/core/pbcc_objects_api.c @@ -77,6 +77,8 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep( char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -102,6 +104,9 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep( if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -292,6 +297,8 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -316,6 +323,10 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, if (end != NULL) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -515,6 +526,8 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -542,6 +555,10 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, if (start) { ADD_URL_PARAM(qparam, start, start); } if (end) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -574,6 +591,12 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, char const* uuid_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -598,6 +621,16 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + + if (limit > 0) { ADD_URL_PARAM_SIZET(qparam, limit, limit); } + if (NULL != start) { ADD_URL_PARAM(qparam, start, start); } + if (NULL != end) { ADD_URL_PARAM(qparam, end, end); } + + if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); @@ -633,6 +666,8 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, size_t limit, char const* start, char const* end, + char const* filter, + char const* sort, enum pubnub_tribool count, enum pubnub_trans pt) { @@ -663,6 +698,10 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, if (start) { ADD_URL_PARAM(qparam, start, start); } if (end) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -695,6 +734,12 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, char const* channel_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -720,6 +765,15 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + + if (limit > 0) { ADD_URL_PARAM_SIZET(qparam, limit, limit); } + if (NULL != start) { ADD_URL_PARAM(qparam, start, start); } + if (NULL != end) { ADD_URL_PARAM(qparam, end, end); } + + if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); diff --git a/core/pbcc_objects_api.h b/core/pbcc_objects_api.h index 55579285..ab64f024 100644 --- a/core/pbcc_objects_api.h +++ b/core/pbcc_objects_api.h @@ -26,6 +26,8 @@ enum pubnub_res pbcc_find_objects_id(struct pbcc_context* pb, char const* file, int line); +// TODO: maybe we should decrease amount of parameters in these functions + /** Prepares the 'get_users' transaction, mostly by formatting the URI of the HTTP request. */ @@ -35,6 +37,8 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); /** Prepares the 'set_uuidmetadata' transaction, mostly by @@ -70,6 +74,8 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); @@ -108,6 +114,8 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); @@ -118,6 +126,12 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, char const* uuid_metadataid, char const* include, char const* update_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt); /** Prepares the 'get_members' transaction, mostly by @@ -129,6 +143,8 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, size_t limit, char const* start, char const* end, + char const* filter, + char const* sort, enum pubnub_tribool count, enum pubnub_trans pt); @@ -139,6 +155,12 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, char const* channel_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt); diff --git a/core/pubnub_objects_api.c b/core/pubnub_objects_api.c index 6d87d93d..9120a7a5 100644 --- a/core/pubnub_objects_api.c +++ b/core/pubnub_objects_api.c @@ -38,6 +38,26 @@ do { json = (obj_buffer); \ } while(0) +const struct pubnub_page_object pubnub_null_page = {NULL, NULL}; + +const struct pubnub_user_data pubnub_null_user_data = {NULL, NULL, NULL, NULL, NULL}; + +const struct pubnub_channel_data pubnub_null_channel_data = {NULL, NULL, NULL}; + + +struct pubnub_getall_metadata_opts pubnub_getall_metadata_defopts(void) +{ + struct pubnub_getall_metadata_opts opts; + opts.include = NULL; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + opts.count = pbccNotSet; + opts.page = pubnub_null_page; + + return opts; +} + enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* include, @@ -45,6 +65,19 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_getall_metadata_opts opts = pubnub_getall_metadata_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_getall_uuidmetadata_ex(pb, opts); +} + + +enum pubnub_res pubnub_getall_uuidmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts) { enum pubnub_res rslt; @@ -57,11 +90,13 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, } pb->trans = PBTT_GETALL_UUIDMETADATA; rslt = pbcc_getall_uuidmetadata_prep(&pb->core, - include, - limit, - start, - end, - count, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GETALL_UUIDMETADATA; @@ -75,6 +110,17 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, } +struct pubnub_set_uuidmetadata_opts pubnub_set_uuidmetadata_defopts(void) +{ + struct pubnub_set_uuidmetadata_opts opts; + opts.uuid = NULL; + opts.include = NULL; + opts.data = pubnub_null_user_data; + + return opts; +} + + enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, char const* uuid_metadataid, char const* include, @@ -92,7 +138,11 @@ enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_UUIDMETADATA; - rslt = pbcc_set_uuidmetadata_prep(&pb->core, uuid_metadataid, include, uuid_metadata_obj, pb->trans); + rslt = pbcc_set_uuidmetadata_prep(&pb->core, + uuid_metadataid, + include, + uuid_metadata_obj, + pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_UUIDMETADATA; pb->core.last_result = PNR_STARTED; @@ -106,6 +156,58 @@ enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, } +enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, + struct pubnub_set_uuidmetadata_opts opts) +{ + enum pubnub_res result; + size_t obj_len = 0; + char* obj_buffer = NULL; + + obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; + obj_len += NULL != opts.data.email ? strlen(opts.data.email) : 0; + obj_len += NULL != opts.data.name ? strlen(opts.data.name) : 0; + obj_len += NULL != opts.data.external_id ? strlen(opts.data.external_id) : 0; + obj_len += NULL != opts.data.profile_url ? strlen(opts.data.profile_url) : 0; + + obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer + strcpy(obj_buffer, "{"); + + // TODO: maybe it will be a good idea to add serialization at some point to this SDK + if (NULL != opts.data.custom) { + strcat(obj_buffer, "\"custom\":"); + strcat(obj_buffer, opts.data.custom); + } + + if (NULL != opts.data.email) { + strcat(obj_buffer, ",\"email\":"); + strcat(obj_buffer, opts.data.email); + } + + if (NULL != opts.data.name) { + strcat(obj_buffer, ",\"name\":"); + strcat(obj_buffer, opts.data.name); + } + + if (NULL != opts.data.external_id) { + strcat(obj_buffer, ",\"externalId\":"); + strcat(obj_buffer, opts.data.external_id); + } + + if (NULL != opts.data.profile_url) { + strcat(obj_buffer, ",\"profileUrl\":"); + strcat(obj_buffer, opts.data.profile_url); + } + + strcat(obj_buffer, "}\0"); + + result = pubnub_set_uuidmetadata(pb, opts.uuid, opts.include, obj_buffer); + free(obj_buffer); + + return result; +} + + + enum pubnub_res pubnub_get_uuidmetadata(pubnub_t* pb, char const* include, char const* uuid_metadataid) @@ -166,6 +268,20 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_getall_metadata_opts opts = pubnub_getall_metadata_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_getall_channelmetadata_ex(pb, opts); +} + + +enum pubnub_res pubnub_getall_channelmetadata_ex(pubnub_t* pb, + struct pubnub_getall_metadata_opts opts) { enum pubnub_res rslt; @@ -178,11 +294,13 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, } pb->trans = PBTT_GETALL_CHANNELMETADATA; rslt = pbcc_getall_channelmetadata_prep(&pb->core, - include, - limit, - start, - end, - count, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GETALL_CHANNELMETADATA; @@ -196,6 +314,16 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, } +struct pubnub_set_channelmetadata_opts pubnub_set_channelmetadata_defopts(void) +{ + struct pubnub_set_channelmetadata_opts opts; + opts.include = NULL; + opts.data = pubnub_null_channel_data; + + return opts; +} + + enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, char const* channel_metadataid, char const* include, @@ -213,7 +341,11 @@ enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_CHANNELMETADATA; - rslt = pbcc_set_channelmetadata_prep(&pb->core, channel_metadataid, include, channel_metadata_obj, pb->trans); + rslt = pbcc_set_channelmetadata_prep(&pb->core, + channel_metadataid, + include, + channel_metadata_obj, + pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_CHANNELMETADATA; pb->core.last_result = PNR_STARTED; @@ -227,6 +359,45 @@ enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, } +enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, + char const* channel, + struct pubnub_set_channelmetadata_opts opts) +{ + enum pubnub_res result; + size_t obj_len = 0; + char* obj_buffer = NULL; + + obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; + obj_len += NULL != opts.data.description ? strlen(opts.data.description) : 0; + obj_len += NULL != opts.data.name ? strlen(opts.data.name) : 0; + + obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer + + strcpy(obj_buffer, "{"); + if (NULL != opts.data.custom) { + strcat(obj_buffer, "\"custom\":"); + strcat(obj_buffer, opts.data.custom); + } + + if (NULL != opts.data.description) { + strcat(obj_buffer, ",\"description\":"); + strcat(obj_buffer, opts.data.description); + } + + if (NULL != opts.data.name) { + strcat(obj_buffer, ",\"name\":"); + strcat(obj_buffer, opts.data.name); + } + + strcat(obj_buffer, "}\0"); + + result = pubnub_set_channelmetadata(pb, channel, opts.include, obj_buffer); + free(obj_buffer); + + return result; +} + + enum pubnub_res pubnub_get_channelmetadata(pubnub_t* pb, char const* include, char const* channel_metadataid) @@ -282,6 +453,20 @@ enum pubnub_res pubnub_remove_channelmetadata(pubnub_t* pb, char const* channel_ } +struct pubnub_membership_opts pubnub_memberships_defopts(void) +{ + struct pubnub_membership_opts opts; + opts.uuid = NULL; + opts.include = NULL; + opts.page = pubnub_null_page; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + + return opts; +} + + enum pubnub_res pubnub_get_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, @@ -289,6 +474,21 @@ enum pubnub_res pubnub_get_memberships(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_get_memberships_ex(pb, opts); +} + + +enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; @@ -301,12 +501,14 @@ enum pubnub_res pubnub_get_memberships(pubnub_t* pb, } pb->trans = PBTT_GET_MEMBERSHIPS; rslt = pbcc_get_memberships_prep(&pb->core, - uuid_metadataid, - include, - limit, - start, - end, - count, + opts.uuid, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GET_MEMBERSHIPS; @@ -324,6 +526,18 @@ enum pubnub_res pubnub_set_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, char const* set_obj) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + + return pubnub_set_memberships_ex(pb, set_obj, opts); +} + + +enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, + char const* channels, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -341,14 +555,20 @@ enum pubnub_res pubnub_set_memberships(pubnub_t* pb, "pubnub_set_memberships", obj_buffer, "{\"set\":", - set_obj); + channels); pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_MEMBERSHIPS; rslt = pbcc_set_memberships_prep(&pb->core, - uuid_metadataid, - include, - set_obj, + opts.uuid, + opts.include, + channels, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_MEMBERSHIPS; @@ -367,6 +587,18 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, char const* remove_obj) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + + return pubnub_remove_memberships_ex(pb, remove_obj, opts); +} + + +enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, + char const* channels, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -384,13 +616,19 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, "pubnub_remove_memberships", obj_buffer, "{\"delete\":", - remove_obj); + channels); pb->method = pubnubUsePATCH; pb->trans = PBTT_REMOVE_MEMBERSHIPS; rslt = pbcc_set_memberships_prep(&pb->core, - uuid_metadataid, - include, - remove_obj, + opts.uuid, + opts.include, + channels, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_REMOVE_MEMBERSHIPS; @@ -405,6 +643,20 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, } +struct pubnub_members_opts pubnub_members_defopts(void) +{ + struct pubnub_members_opts opts; + opts.include = NULL; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + opts.page = pubnub_null_page; + opts.count = pbccNotSet; + + return opts; +} + + enum pubnub_res pubnub_get_members(pubnub_t* pb, char const* channel_metadataid, char const* include, @@ -412,6 +664,21 @@ enum pubnub_res pubnub_get_members(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_get_members_ex(pb, channel_metadataid, opts); +} + + +enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, + char const* channel, + struct pubnub_members_opts opts) { enum pubnub_res rslt; @@ -424,12 +691,14 @@ enum pubnub_res pubnub_get_members(pubnub_t* pb, } pb->trans = PBTT_GET_MEMBERS; rslt = pbcc_get_members_prep(&pb->core, - channel_metadataid, - include, - limit, - start, - end, - count, + channel, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.filter, + opts.sort, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GET_MEMBERS; @@ -450,6 +719,7 @@ enum pubnub_res pubnub_add_members(pubnub_t* pb, { char obj_buffer[PUBNUB_BUF_MAXLEN]; enum pubnub_res rslt; + struct pubnub_members_opts defaults = pubnub_members_defopts(); PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); @@ -470,6 +740,12 @@ enum pubnub_res pubnub_add_members(pubnub_t* pb, channel_metadataid, include, update_obj, + defaults.filter, + defaults.sort, + defaults.limit, + defaults.page.next, + defaults.page.prev, + defaults.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_ADD_MEMBERS; @@ -488,6 +764,18 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, char const* channel_metadataid, char const* include, char const* set_obj) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + + return pubnub_set_members_ex(pb, channel_metadataid, set_obj, opts); +} + + +enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -505,13 +793,19 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, "pubnub_set_members", obj_buffer, "{\"set\":", - set_obj); + uuids); pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_MEMBERS; rslt = pbcc_set_members_prep(&pb->core, - channel_metadataid, - include, - set_obj, + channel, + opts.include, + uuids, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_MEMBERS; @@ -526,10 +820,23 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, } + enum pubnub_res pubnub_remove_members(pubnub_t* pb, char const* channel_metadataid, char const* include, char const* remove_obj) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + + return pubnub_remove_members_ex(pb, channel_metadataid, remove_obj, opts); +} + + +enum pubnub_res pubnub_remove_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -547,13 +854,19 @@ enum pubnub_res pubnub_remove_members(pubnub_t* pb, "pubnub_remove_members", obj_buffer, "{\"delete\":", - remove_obj); + uuids); pb->method = pubnubUsePATCH; pb->trans = PBTT_REMOVE_MEMBERS; rslt = pbcc_set_members_prep(&pb->core, - channel_metadataid, - include, - remove_obj, + channel, + opts.include, + uuids, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_REMOVE_MEMBERS; @@ -567,5 +880,6 @@ enum pubnub_res pubnub_remove_members(pubnub_t* pb, return rslt; } + #endif /* PUBNUB_USE_OBJECTS_API */ diff --git a/core/pubnub_objects_api.h b/core/pubnub_objects_api.h index 6f288890..43b14780 100644 --- a/core/pubnub_objects_api.h +++ b/core/pubnub_objects_api.h @@ -8,6 +8,7 @@ #include "pubnub_api_types.h" #include "lib/pb_extern.h" +#include "stddef.h" #include @@ -61,19 +62,19 @@ struct pubnub_channel_data { /** The "null" page object, which is used to indicate that there is no next or previous page. Also it can be used when there is no will to pass page as a parameter */ -PUBNUB_EXTERN const struct pubnub_page_object pubnub_null_page = { NULL, NULL }; +PUBNUB_EXTERN const struct pubnub_page_object pubnub_null_page; /** The "null" user data object, which is used to indicate that there is no user data. Also it can be used when there is no will to pass user data as a parameter */ -PUBNUB_EXTERN const struct pubnub_user_data pubnub_null_user_data = { NULL, NULL, NULL, NULL, NULL }; +PUBNUB_EXTERN const struct pubnub_user_data pubnub_null_user_data; /** The "null" channel data object, which is used to indicate that there is no channel data. Also it can be used when there is no will to pass channel data as a parameter */ -PUBNUB_EXTERN const struct pubnub_channel_data pubnub_null_channel_data = { NULL, NULL, NULL }; +PUBNUB_EXTERN const struct pubnub_channel_data pubnub_null_channel_data; /** Options for the getall_*metadata functions */ @@ -110,7 +111,7 @@ struct pubnub_getall_metadata_opts { - sort: NULL - limit: 100 - page: pubnub_null_page - - count: pbNotSet + - count: pbccNotSet @see pubnub_getall_metadata_opts @see pubnub_null_page @@ -353,7 +354,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_channelmetadata(pubnub_t* pb, char c /** Options for the pubnub_get_memberships function */ -struct pubnub_membership_data { +struct pubnub_membership_opts { /** The UUID to retrieve the memberships. */ char const* uuid; @@ -376,12 +377,15 @@ struct pubnub_membership_data { /** Pagination object. @see pubnub_page_object */ struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; }; /** Default options for the pubnub_get_memberships function Values are set as follows: - - uuid: NULL (`pubnub_get_memberships_ex` will take the user_id from the context on NULL) + - uuid: NULL (`pubnub_*_memberships_ex` will take the user_id from the context on NULL) - include: NULL - filter: NULL - sort: NULL @@ -392,7 +396,7 @@ struct pubnub_membership_data { @return Default options for the get_memberships function */ -PUBNUB_EXTERN struct pubnub_membership_data pubnub_memberships_defopts(); +PUBNUB_EXTERN struct pubnub_membership_opts pubnub_memberships_defopts(); /** Returns the channel memberships of the user specified by @p uuid_metadataid, optionally including @@ -434,7 +438,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships(pubnub_t* pb, @param opts The options for the get_memberships function. @return #PNR_STARTED on success, an error otherwise */ -PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, struct pubnub_membership_data opts); +PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, struct pubnub_membership_opts opts); /** Add/Update the channel memberships of the UUID specified by @p metadata_uuid. Uses the `set` property @@ -498,7 +502,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships(pubnub_t* pb, @param opts The options for the set_memberships function. @return #PNR_STARTED on success, an error otherwise */ -PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_data opts); +PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_opts opts); /** Removes the memberships of the user specified by @p uuid_metadataid. Uses the `delete` property @@ -551,11 +555,11 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, @return #PNR_STARTED on success, an error otherwise */ -PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_data opts); +PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_opts opts); /** Options for the pubnub_*_members functions */ -struct pubnub_members_data { +struct pubnub_members_opts { /** The comma delimited (C) string with additional/complex attributes to include in response. Use NULL if you don't want to retrieve additional attributes. */ char const* include; @@ -594,7 +598,7 @@ struct pubnub_members_data { @return Default options for the get_members function */ -PUBNUB_EXTERN struct pubnub_members_data pubnub_get_members_defopts(); +PUBNUB_EXTERN struct pubnub_members_opts pubnub_members_defopts(); /** Returns all users in the channel specified with @p channel_metadataid, optionally including @@ -636,7 +640,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_members(pubnub_t* pb, @param opts The options for the get_members function. @return #PNR_STARTED on success, an error otherwise */ -PUBNUB_EXTERN enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, char const* channel, struct pubnub_members_data opts); +PUBNUB_EXTERN enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, char const* channel, struct pubnub_members_opts opts); /** Adds the list of members of the channel specified with @p channel_metadataid. Uses the `add` @@ -722,7 +726,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_members(pubnub_t* pb, PUBNUB_EXTERN enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, char const* channel, char const* uuids, - struct pubnub_members_data opts); + struct pubnub_members_opts opts); /** Removes the list of members of the space specified with @p space_id. Uses the `remove` @@ -777,7 +781,7 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_members(pubnub_t* pb, PUBNUB_EXTERN enum pubnub_res pubnub_remove_members_ex(pubnub_t* pb, char const* channel, char const* uuids, - struct pubnub_members_data opts); + struct pubnub_members_opts opts); #endif /* !defined INC_PUBNUB_OBJECTS_API */ diff --git a/core/samples/pubnub_objects_api_sample.c b/core/samples/pubnub_objects_api_sample.c new file mode 100644 index 00000000..13f7da74 --- /dev/null +++ b/core/samples/pubnub_objects_api_sample.c @@ -0,0 +1,502 @@ +#include "pubnub_api_types.h" +#include "pubnub_blocking_io.h" +#include "pubnub_pubsubapi.h" +#include "core/pubnub_helper.h" +#include "core/pubnub_alloc.h" +#include "core/pubnub_ntf_sync.h" +#include "core/pubnub_objects_api.h" +#include +#include + +// This sample demo is split into 4 sections: +// 1. UUID metadata section +// 2. Channels metadata section +// 3. Memberships section +// 4. Members section +// +// You can navigate to each section by searching for the section name. +// +// Each section shows basic usage of the Pubnub Objects API. +// There are more options available for each API call, +// which can be found in the Pubnub Objects API documentation. + +static void sync_sample_free(pubnub_t* p); + +int main(void) { + // No demo keysets as app context is not applicable to it +// char* publish_key = getenv("PUBNUB_PUBLISH_KEY"); +// char* subscribe_key = getenv("PUBNUB_SUBSCRIBE_KEY"); + char* publish_key = "pub-c-2451c2cf-9f04-446b-8f85-e06564095e55"; + char* subscribe_key = "sub-c-d16ff59f-b415-4ef9-8c29-ddda64fa2b43"; + + enum pubnub_res result; + + pubnub_t* pb = pubnub_alloc(); + if (NULL == pb) { + printf("Failed to allocate Pubnub context!\n"); + return -1; + } + + pubnub_init(pb, publish_key, subscribe_key); + pubnub_set_user_id(pb, "my_user"); + + // Depending on requirements, you can use non-blocking I/O + pubnub_set_blocking_io(pb); + + printf("~~~~~~~~~~~~~~~~~~uuid metadata section~~~~~~~~~~~~~~~~~~\n"); + + printf("Set users' metadata\n"); + struct pubnub_set_uuidmetadata_opts set_opts = pubnub_set_uuidmetadata_defopts(); + set_opts.data.name = "\"my_name\""; + set_opts.data.external_id = "\"my_external_id\""; + set_opts.data.profile_url = "\"my_profile_url\""; + set_opts.data.email = "\"my_email\""; + set_opts.data.custom = "{\"key\":\"value\"}"; + set_opts.include = "\"custom\""; + + // we didn't set the UUID, so it will be the one from the context + result = pubnub_set_uuidmetadata_ex(pb, set_opts); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set UUID metadata successful!\n"); + } else { + printf("Set UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + struct pubnub_set_uuidmetadata_opts set_opts2 = pubnub_set_uuidmetadata_defopts(); + set_opts2.data.custom = "{\"key\":\"totally different value\"}"; + set_opts2.uuid = "\"some_user\""; + + result = pubnub_set_uuidmetadata_ex(pb, set_opts2); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set UUID metadata successful!\n"); + } else { + printf("Set UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("Get users' metadata\n"); + struct pubnub_getall_metadata_opts getall_opts = pubnub_getall_metadata_defopts(); + // getall_opts.page.next = you can retrieve the next page in the response when the response is paginated + // getall_opts.page.prev = as above + getall_opts.limit = 1; + getall_opts.include = "custom"; + getall_opts.filter = "name=='my_name'"; + getall_opts.count = pbccTrue; + getall_opts.sort = "name:desc"; + + result = pubnub_getall_uuidmetadata_ex(pb, getall_opts); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get UUID metadata successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get users' metadata by UUID\n"); + result = pubnub_get_uuidmetadata(pb, "custom", "my_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get UUID metadata by UUID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get UUID metadata by UUID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove users' metadata by UUID\n"); + + result = pubnub_remove_uuidmetadata(pb, "my_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove UUID metadata successful!\n"); + } else { + printf("Remove UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + result = pubnub_remove_uuidmetadata(pb, "some_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove UUID metadata successful!\n"); + } else { + printf("Remove UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~channels metadata section~~~~~~~~~~~~~~~~\n"); + + printf("Set channels' metadata\n"); + struct pubnub_set_channelmetadata_opts set_channel_opts = pubnub_set_channelmetadata_defopts(); + set_channel_opts.data.name = "\"my_channel_name\""; + set_channel_opts.data.description = "\"my_channel_description\""; + set_channel_opts.data.custom = "{\"key\":\"value\"}"; + set_channel_opts.include = "\"custom\""; + + result = pubnub_set_channelmetadata_ex(pb, "channel_id", set_channel_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set channel metadata successful!\n"); + } else { + printf("Set channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' metadata\n"); + + struct pubnub_getall_metadata_opts getall_channel_opts = pubnub_getall_metadata_defopts(); + getall_channel_opts.limit = 1; + getall_channel_opts.include = "custom"; + getall_channel_opts.filter = "custom.key=='value'"; + getall_channel_opts.count = pbccTrue; + getall_channel_opts.sort = "name:desc"; + + result = pubnub_getall_channelmetadata_ex(pb, getall_channel_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get channel metadata successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' metadata by channel ID\n"); + + result = pubnub_get_channelmetadata(pb, "custom", "channel_id"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get channel metadata by channel ID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get channel metadata by channel ID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove channels' metadata by channel ID\n"); + result = pubnub_remove_channelmetadata(pb, "channel_id"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove channel metadata successful!\n"); + } else { + printf("Remove channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~~~~memberships section~~~~~~~~~~~~~~~~~~~\n"); + + printf("Set users' memberships\n"); + struct pubnub_membership_opts set_memberships_opts = pubnub_memberships_defopts(); + set_memberships_opts.include = "custom"; + set_memberships_opts.limit = 1; + set_memberships_opts.sort = "channel.name:desc"; + set_memberships_opts.filter = "custom.key=='value'"; + set_memberships_opts.count = pbccTrue; + + const char* channels_meta = "[" + "{" + "\"channel\":{ \"id\": \"main-channel-id\" }," + "\"custom\": {" + "\"starred\": true" + "}" + "}," + "{" + "\"channel\":{ \"id\": \"channel-0\" }," + "\"some_key\": {" + "\"other_key\": \"other_value\"" + "}" + "}" + "]"; + + result = pubnub_set_memberships_ex(pb, channels_meta, set_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set memberships successful!\n"); + } else { + printf("Set memberships failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get users' memberships\n"); + + struct pubnub_membership_opts getall_memberships_opts = pubnub_memberships_defopts(); + getall_memberships_opts.limit = 1; + getall_memberships_opts.include = "custom"; + getall_memberships_opts.filter = "custom.key=='value'"; + getall_memberships_opts.count = pbccTrue; + getall_memberships_opts.sort = "channel.name:desc"; + + result = pubnub_set_memberships_ex(pb, "", getall_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get memberships successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get memberships failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get users' memberships by UUID\n"); + + struct pubnub_membership_opts get_memberships_opts = pubnub_memberships_defopts(); + get_memberships_opts.limit = 1; + get_memberships_opts.include = "custom"; + get_memberships_opts.filter = "custom.key=='value'"; + get_memberships_opts.count = pbccTrue; + get_memberships_opts.sort = "channel.name:desc"; + + result = pubnub_get_memberships_ex(pb, get_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get memberships by UUID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get memberships by UUID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove users' memberships by UUID\n"); + + struct pubnub_membership_opts remove_memberships_opts = pubnub_memberships_defopts(); + remove_memberships_opts.include = "custom"; + remove_memberships_opts.limit = 1; + remove_memberships_opts.sort = "channel.name:desc"; + remove_memberships_opts.filter = "custom.key=='value'"; + remove_memberships_opts.count = pbccTrue; + + const char* channels_meta_remove = "[" + "{" + "\"id\": \"main-channel-id\"" + "}," + "{" + "\"id\": \"channel-0\"" + "}" + "]"; + + result = pubnub_remove_memberships_ex(pb, channels_meta_remove, remove_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove memberships successful!\n"); + } else { + printf("Remove memberships failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~~~~~~members section~~~~~~~~~~~~~~~~~~~~~\n"); + + printf("Set channels' members\n"); + + struct pubnub_members_opts set_members_opts = pubnub_members_defopts(); + set_members_opts.include = "custom"; + set_members_opts.limit = 1; + set_members_opts.sort = "uuid.name:desc"; + set_members_opts.filter = "custom.key=='value'"; + set_members_opts.count = pbccTrue; + + const char* members_meta = "[" + "{" + "\"uuid\":{ \"id\": \"main-user-id\" }," + "\"custom\": {" + "\"starred\": true" + "}" + "}," + "{" + "\"uuid\":{ \"id\": \"user-0\" }," + "\"some_key\": {" + "\"other_key\": \"other_value\"" + "}" + "}" + "]"; + + result = pubnub_set_members_ex(pb, "channel_id", members_meta, set_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set members successful!\n"); + } else { + printf("Set members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' members\n"); + + struct pubnub_members_opts get_members_opts = pubnub_members_defopts(); + get_members_opts.limit = 1; + get_members_opts.include = "custom"; + get_members_opts.filter = "custom.key=='value'"; + get_members_opts.count = pbccTrue; + get_members_opts.sort = "uuid.name:desc"; + + result = pubnub_get_members_ex(pb, "channel_id", get_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get members successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove channels' members by UUID\n"); + + struct pubnub_members_opts remove_members_opts = pubnub_members_defopts(); + remove_members_opts.include = "custom"; + remove_members_opts.limit = 1; + remove_members_opts.sort = "uuid.name:desc"; + remove_members_opts.filter = "custom.key=='value'"; + remove_members_opts.count = pbccTrue; + + const char* members_meta_remove = "[" + "{" + "\"id\": \"main-user-id\"" + "}," + "{" + "\"id\": \"user-0\"" + "}" + "]"; + + result = pubnub_remove_members_ex(pb, "channel_id", members_meta_remove, remove_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove members successful!\n"); + } else { + printf("Remove members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + // ~~~~END OF SAMPLE~~~~ + + sync_sample_free(pb); + + return 0; +} + +static void sync_sample_free(pubnub_t* p) +{ + if (PN_CANCEL_STARTED == pubnub_cancel(p)) { + enum pubnub_res pnru = pubnub_await(p); + if (pnru != PNR_OK) { + printf("Awaiting cancel failed: %d('%s')\n", + pnru, + pubnub_res_2_string(pnru)); + } + } + if (pubnub_free(p) != 0) { + printf("Failed to free the Pubnub context\n"); + } +} + + From 11acdfe639f4c4f19bd030d76c6f111b0a0d4167 Mon Sep 17 00:00:00 2001 From: Xavrax Date: Mon, 29 Jul 2024 03:47:51 +0200 Subject: [PATCH 3/8] fixed whole example --- core/pubnub_objects_api.c | 8 +++ core/pubnub_objects_api.h | 31 ++++++------ core/samples/pubnub_objects_api_sample.c | 63 +++++++----------------- 3 files changed, 39 insertions(+), 63 deletions(-) diff --git a/core/pubnub_objects_api.c b/core/pubnub_objects_api.c index 9120a7a5..6a19bd7a 100644 --- a/core/pubnub_objects_api.c +++ b/core/pubnub_objects_api.c @@ -492,6 +492,10 @@ enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, { enum pubnub_res rslt; + if (NULL == opts.uuid) { + opts.uuid = pb->core.user_id; + } + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); @@ -602,6 +606,10 @@ enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; + + if (NULL == opts.uuid) { + opts.uuid = pb->core.user_id; + } PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); diff --git a/core/pubnub_objects_api.h b/core/pubnub_objects_api.h index 43b14780..67fc967d 100644 --- a/core/pubnub_objects_api.h +++ b/core/pubnub_objects_api.h @@ -536,13 +536,13 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, to perform those operations on one, or more memberships. An example for @channels: [ - { - "id": "main-channel-id" - }, - { - "id": "channel-0" - } - ] + { + "channel":{ "id": "main-channel-id" } + }, + { + "channel":{ "id": "channel-0" } + } + ] Use `pubnub_memberships_defopts()` to get the default options. @@ -733,16 +733,13 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, property to perform the operation on one or more members. An example for @update_obj: [ - { - "id": "some-user-id", - "custom": { - "starred": true - } - }, - { - "id": "user-0-id" - } - ] + { + "uuid":{ "id": "main-user-id" } + }, + { + "uuid":{ "id": "user-0" } + } + ] @param pb The pubnub context. Can't be NULL @param channel_metadataid The Channel ID. diff --git a/core/samples/pubnub_objects_api_sample.c b/core/samples/pubnub_objects_api_sample.c index 13f7da74..99e9ee49 100644 --- a/core/samples/pubnub_objects_api_sample.c +++ b/core/samples/pubnub_objects_api_sample.c @@ -24,10 +24,8 @@ static void sync_sample_free(pubnub_t* p); int main(void) { // No demo keysets as app context is not applicable to it -// char* publish_key = getenv("PUBNUB_PUBLISH_KEY"); -// char* subscribe_key = getenv("PUBNUB_SUBSCRIBE_KEY"); - char* publish_key = "pub-c-2451c2cf-9f04-446b-8f85-e06564095e55"; - char* subscribe_key = "sub-c-d16ff59f-b415-4ef9-8c29-ddda64fa2b43"; + char* publish_key = getenv("PUBNUB_PUBLISH_KEY"); + char* subscribe_key = getenv("PUBNUB_SUBSCRIBE_KEY"); enum pubnub_res result; @@ -288,43 +286,15 @@ int main(void) { pubnub_res_2_string(result)); } - sleep(1); - printf("Get users' memberships\n"); - - struct pubnub_membership_opts getall_memberships_opts = pubnub_memberships_defopts(); - getall_memberships_opts.limit = 1; - getall_memberships_opts.include = "custom"; - getall_memberships_opts.filter = "custom.key=='value'"; - getall_memberships_opts.count = pbccTrue; - getall_memberships_opts.sort = "channel.name:desc"; - - result = pubnub_set_memberships_ex(pb, "", getall_memberships_opts); - - if (PNR_STARTED == result) { - result = pubnub_await(pb); - } - - if (PNR_OK == result) { - printf("Get memberships successful!\n"); - - for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { - printf("Response: %s\n", response); - } - } else { - printf("Get memberships failed with code: %d('%s')\n", - result, - pubnub_res_2_string(result)); - } - sleep(1); printf("Get users' memberships by UUID\n"); struct pubnub_membership_opts get_memberships_opts = pubnub_memberships_defopts(); get_memberships_opts.limit = 1; get_memberships_opts.include = "custom"; - get_memberships_opts.filter = "custom.key=='value'"; + get_memberships_opts.filter = "custom.starred==true"; get_memberships_opts.count = pbccTrue; - get_memberships_opts.sort = "channel.name:desc"; + get_memberships_opts.sort = "channel.id:desc"; result = pubnub_get_memberships_ex(pb, get_memberships_opts); @@ -349,19 +319,20 @@ int main(void) { struct pubnub_membership_opts remove_memberships_opts = pubnub_memberships_defopts(); remove_memberships_opts.include = "custom"; remove_memberships_opts.limit = 1; - remove_memberships_opts.sort = "channel.name:desc"; - remove_memberships_opts.filter = "custom.key=='value'"; + remove_memberships_opts.sort = "channel.id:desc"; + remove_memberships_opts.filter = "custom.starred==true"; remove_memberships_opts.count = pbccTrue; const char* channels_meta_remove = "[" "{" - "\"id\": \"main-channel-id\"" + "\"channel\":{ \"id\": \"main-channel-id\" }" "}," "{" - "\"id\": \"channel-0\"" + "\"channel\":{ \"id\": \"channel-0\" }" "}" "]"; + result = pubnub_remove_memberships_ex(pb, channels_meta_remove, remove_memberships_opts); if (PNR_STARTED == result) { @@ -383,8 +354,8 @@ int main(void) { struct pubnub_members_opts set_members_opts = pubnub_members_defopts(); set_members_opts.include = "custom"; set_members_opts.limit = 1; - set_members_opts.sort = "uuid.name:desc"; - set_members_opts.filter = "custom.key=='value'"; + set_members_opts.sort = "uuid.id:desc"; + set_members_opts.filter = "custom.starred==true"; set_members_opts.count = pbccTrue; const char* members_meta = "[" @@ -422,9 +393,9 @@ int main(void) { struct pubnub_members_opts get_members_opts = pubnub_members_defopts(); get_members_opts.limit = 1; get_members_opts.include = "custom"; - get_members_opts.filter = "custom.key=='value'"; + get_members_opts.filter = "custom.starred==true"; get_members_opts.count = pbccTrue; - get_members_opts.sort = "uuid.name:desc"; + get_members_opts.sort = "uuid.id:desc"; result = pubnub_get_members_ex(pb, "channel_id", get_members_opts); @@ -450,16 +421,16 @@ int main(void) { struct pubnub_members_opts remove_members_opts = pubnub_members_defopts(); remove_members_opts.include = "custom"; remove_members_opts.limit = 1; - remove_members_opts.sort = "uuid.name:desc"; - remove_members_opts.filter = "custom.key=='value'"; + remove_members_opts.sort = "uuid.id:desc"; + remove_members_opts.filter = "custom.starred==true"; remove_members_opts.count = pbccTrue; const char* members_meta_remove = "[" "{" - "\"id\": \"main-user-id\"" + "\"uuid\":{ \"id\": \"main-user-id\" }" "}," "{" - "\"id\": \"user-0\"" + "\"uuid\":{ \"id\": \"user-0\" }" "}" "]"; From edae032496b8d472e35fa001b3509ae477cb3c50 Mon Sep 17 00:00:00 2001 From: Xavrax Date: Mon, 29 Jul 2024 04:41:09 +0200 Subject: [PATCH 4/8] some fixes --- CMakeLists.txt | 13 +++++++++++++ core/c99/stdbool.h | 6 +++++- posix/pubnub_version_posix.c | 8 ++++++-- windows/pubnub_version_windows.c | 8 ++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5b088fe..aee05ca2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ log_set(CUSTOM_OPENSSL_INCLUDE_DIR "include" "OpenSSL include directory relative log_set(EXAMPLE "all" "Build example with provided name (use 'all' for all examples) [EXAMPLES=ON needed]") log_set(CGREEN_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/cgreen" "CGreen root directory [UNIT_TEST=ON needed]") log_set(LOG_LEVEL "WARNING" "Log level [TRACE/DEBUG/INFO/WARNING/ERROR]") +log_set(CUSTOM_BOOL_TYPE "xddd" "Type of bool for platform differences. Select whatever works for you that accepts 0/1 values") if (${OPENSSL} AND ${MBEDTLS}) message(FATAL_ERROR "You can't use both OpenSSL and mbedTLS at the same time!") @@ -143,6 +144,13 @@ if(${WITH_CPP}) endif() endif() +if(NOT ${CUSTOM_BOOL_TYPE} STREQUAL "") + message(STATUS "Using custom bool type: ${BOOL_TYPE}") + set(FLAGS "\ + ${FLAGS} \ + -D PUBNUB_BOOL_TYPE=${BOOL_TYPE}") +endif() + set(CORE_SOURCEFILES ${CMAKE_CURRENT_LIST_DIR}/core/pbcc_set_state.c ${CMAKE_CURRENT_LIST_DIR}/core/pubnub_pubsubapi.c @@ -674,6 +682,11 @@ if(${EXAMPLES}) pubnub_crypto_module_sample ${EXAMPLE_LIST}) endif() + if (${USE_OBJECTS_API}) + set(EXAMPLE_LIST + pubnub_objects_api_sample + ${EXAMPLE_LIST}) + endif() endif() else() message(STATUS "Building example ${EXAMPLE}") diff --git a/core/c99/stdbool.h b/core/c99/stdbool.h index c9c7ce3e..ad6ed99f 100644 --- a/core/c99/stdbool.h +++ b/core/c99/stdbool.h @@ -5,6 +5,10 @@ #define false 0 #define true 1 +#ifdef PUBNUB_BOOL_TYPE +#define bool PUBNUB_BOOL_TYPE +#else #define bool int +#endif -#endif /* !defined __cplusplus */ \ No newline at end of file +#endif /* !defined __cplusplus */ diff --git a/posix/pubnub_version_posix.c b/posix/pubnub_version_posix.c index de1323c1..ffaa6ec6 100644 --- a/posix/pubnub_version_posix.c +++ b/posix/pubnub_version_posix.c @@ -6,6 +6,10 @@ #define PUBNUB_SDK_NAME "POSIX" +#ifndef PUBNUB_SDK_VERSION_SUFFIX +#define PUBNUB_SDK_VERSION_SUFFIX +#endif + char const *pubnub_sdk_name(void) { @@ -21,12 +25,12 @@ char const *pubnub_version(void) char const *pubnub_uname(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } char const *pubnub_uagent(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } diff --git a/windows/pubnub_version_windows.c b/windows/pubnub_version_windows.c index 8ba0b199..684c874b 100644 --- a/windows/pubnub_version_windows.c +++ b/windows/pubnub_version_windows.c @@ -6,6 +6,10 @@ #define PUBNUB_SDK_NAME "Windows" +#ifndef PUBNUB_SDK_VERSION_SUFFIX +#define PUBNUB_SDK_VERSION_SUFFIX +#endif + char const *pubnub_sdk_name(void) { @@ -21,11 +25,11 @@ char const *pubnub_version(void) char const *pubnub_uname(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } char const *pubnub_uagent(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } From 3605798893b90e2d5368e8934928f87e9476cb21 Mon Sep 17 00:00:00 2001 From: Xavrax Date: Mon, 29 Jul 2024 04:43:02 +0200 Subject: [PATCH 5/8] xddd --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aee05ca2..25e06b3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ log_set(CUSTOM_OPENSSL_INCLUDE_DIR "include" "OpenSSL include directory relative log_set(EXAMPLE "all" "Build example with provided name (use 'all' for all examples) [EXAMPLES=ON needed]") log_set(CGREEN_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/cgreen" "CGreen root directory [UNIT_TEST=ON needed]") log_set(LOG_LEVEL "WARNING" "Log level [TRACE/DEBUG/INFO/WARNING/ERROR]") -log_set(CUSTOM_BOOL_TYPE "xddd" "Type of bool for platform differences. Select whatever works for you that accepts 0/1 values") +log_set(CUSTOM_BOOL_TYPE "" "Type of bool for platform differences. Select whatever works for you that accepts 0/1 values") if (${OPENSSL} AND ${MBEDTLS}) message(FATAL_ERROR "You can't use both OpenSSL and mbedTLS at the same time!") From 57294a17610591df7ee432bfc1f533d0ed8b789f Mon Sep 17 00:00:00 2001 From: Xavrax Date: Mon, 29 Jul 2024 06:26:27 +0200 Subject: [PATCH 6/8] fix PAM api in CMAKE --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25e06b3c..ca87fe46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,6 +380,9 @@ endif() if(${USE_GRANT_TOKEN_API}) set(FEATURE_SOURCEFILES ${FEATURE_SOURCEFILES} + ${CMAKE_CURRENT_LIST_DIR}/lib/cbor/cborparser.c + ${CMAKE_CURRENT_LIST_DIR}/lib/cbor/cborerrorstrings.c + ${CMAKE_CURRENT_LIST_DIR}/lib/cbor/cborparser_dup_string.c ${CMAKE_CURRENT_LIST_DIR}/core/pbcc_grant_token_api.c ${CMAKE_CURRENT_LIST_DIR}/core/pubnub_grant_token_api.c) endif() @@ -681,6 +684,11 @@ if(${EXAMPLES}) set(EXAMPLE_LIST pubnub_crypto_module_sample ${EXAMPLE_LIST}) + if (${USE_GRANT_TOKEN_API}) + set(EXAMPLE_LIST + pubnub_sync_grant_token_sample + ${EXAMPLE_LIST}) + endif() endif() if (${USE_OBJECTS_API}) set(EXAMPLE_LIST From 21d14cb775bf3feceefd2ab28dc63e368aed9bfe Mon Sep 17 00:00:00 2001 From: Serhii Mamontov Date: Mon, 29 Jul 2024 22:54:41 +0300 Subject: [PATCH 7/8] refactor: replace `strcat` vs `snprintf` refactor: update demo application Remove some App Context configuration options JSON "stringify" (remove escaped double quotes). --- core/pubnub_objects_api.c | 78 +++++++++++++++--------- core/pubnub_objects_api.h | 3 - core/samples/pubnub_objects_api_sample.c | 18 +++--- 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/core/pubnub_objects_api.c b/core/pubnub_objects_api.c index 6a19bd7a..7c00af7d 100644 --- a/core/pubnub_objects_api.c +++ b/core/pubnub_objects_api.c @@ -157,11 +157,11 @@ enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, - struct pubnub_set_uuidmetadata_opts opts) + struct pubnub_set_uuidmetadata_opts opts) { + char* obj_buffer = NULL; enum pubnub_res result; - size_t obj_len = 0; - char* obj_buffer = NULL; + size_t obj_len = 0; obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; obj_len += NULL != opts.data.email ? strlen(opts.data.email) : 0; @@ -170,35 +170,48 @@ enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, obj_len += NULL != opts.data.profile_url ? strlen(opts.data.profile_url) : 0; obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer - strcpy(obj_buffer, "{"); + int offset = snprintf(obj_buffer, obj_len, "{"); // TODO: maybe it will be a good idea to add serialization at some point to this SDK if (NULL != opts.data.custom) { - strcat(obj_buffer, "\"custom\":"); - strcat(obj_buffer, opts.data.custom); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "\"custom\":%s", + opts.data.custom); } if (NULL != opts.data.email) { - strcat(obj_buffer, ",\"email\":"); - strcat(obj_buffer, opts.data.email); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"email\":\"%s\"", + offset > 1 ? "," : "", + opts.data.email); } if (NULL != opts.data.name) { - strcat(obj_buffer, ",\"name\":"); - strcat(obj_buffer, opts.data.name); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"name\":\"%s\"", + offset > 1 ? "," : "", + opts.data.name); } if (NULL != opts.data.external_id) { - strcat(obj_buffer, ",\"externalId\":"); - strcat(obj_buffer, opts.data.external_id); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"externalId\":\"%s\"", + offset > 1 ? "," : "", + opts.data.external_id); } if (NULL != opts.data.profile_url) { - strcat(obj_buffer, ",\"profileUrl\":"); - strcat(obj_buffer, opts.data.profile_url); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"profileUrl\":\"%s\"", + offset > 1 ? "," : "", + opts.data.profile_url); } - - strcat(obj_buffer, "}\0"); + snprintf(obj_buffer + offset, obj_len - offset, "}\0"); result = pubnub_set_uuidmetadata(pb, opts.uuid, opts.include, obj_buffer); free(obj_buffer); @@ -359,37 +372,42 @@ enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, } -enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, - char const* channel, - struct pubnub_set_channelmetadata_opts opts) +enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, + char const* channel, + struct pubnub_set_channelmetadata_opts opts) { + char* obj_buffer = NULL; enum pubnub_res result; - size_t obj_len = 0; - char* obj_buffer = NULL; + size_t obj_len = 0; obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; obj_len += NULL != opts.data.description ? strlen(opts.data.description) : 0; obj_len += NULL != opts.data.name ? strlen(opts.data.name) : 0; obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer - - strcpy(obj_buffer, "{"); + int offset = snprintf(obj_buffer, obj_len, "{"); + if (NULL != opts.data.custom) { - strcat(obj_buffer, "\"custom\":"); - strcat(obj_buffer, opts.data.custom); + offset += snprintf(obj_buffer, obj_len, "\"custom\":%s", opts.data.custom); } if (NULL != opts.data.description) { - strcat(obj_buffer, ",\"description\":"); - strcat(obj_buffer, opts.data.description); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"description\":\"%s\"", + offset > 1 ? "," : "", + opts.data.description); } if (NULL != opts.data.name) { - strcat(obj_buffer, ",\"name\":"); - strcat(obj_buffer, opts.data.name); + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"name\":\"%s\"", + offset > 1 ? "," : "", + opts.data.name); } - strcat(obj_buffer, "}\0"); + offset += snprintf(obj_buffer + offset, obj_len - offset, "}\0"); result = pubnub_set_channelmetadata(pb, channel, opts.include, obj_buffer); free(obj_buffer); diff --git a/core/pubnub_objects_api.h b/core/pubnub_objects_api.h index 67fc967d..73a61ded 100644 --- a/core/pubnub_objects_api.h +++ b/core/pubnub_objects_api.h @@ -8,9 +8,6 @@ #include "pubnub_api_types.h" #include "lib/pb_extern.h" -#include "stddef.h" - -#include /** Data pagination object. This object helps to paginate through the data. It is more readable form of `start` and `end` parameters in objects API. diff --git a/core/samples/pubnub_objects_api_sample.c b/core/samples/pubnub_objects_api_sample.c index 99e9ee49..7c84d1ad 100644 --- a/core/samples/pubnub_objects_api_sample.c +++ b/core/samples/pubnub_objects_api_sample.c @@ -45,12 +45,12 @@ int main(void) { printf("Set users' metadata\n"); struct pubnub_set_uuidmetadata_opts set_opts = pubnub_set_uuidmetadata_defopts(); - set_opts.data.name = "\"my_name\""; - set_opts.data.external_id = "\"my_external_id\""; - set_opts.data.profile_url = "\"my_profile_url\""; - set_opts.data.email = "\"my_email\""; + set_opts.data.name = "my_name"; + set_opts.data.external_id = "my_external_id"; + set_opts.data.profile_url = "my_profile_url"; + set_opts.data.email = "my_email"; set_opts.data.custom = "{\"key\":\"value\"}"; - set_opts.include = "\"custom\""; + set_opts.include = "custom"; // we didn't set the UUID, so it will be the one from the context result = pubnub_set_uuidmetadata_ex(pb, set_opts); @@ -68,7 +68,7 @@ int main(void) { struct pubnub_set_uuidmetadata_opts set_opts2 = pubnub_set_uuidmetadata_defopts(); set_opts2.data.custom = "{\"key\":\"totally different value\"}"; - set_opts2.uuid = "\"some_user\""; + set_opts2.uuid = "some_user"; result = pubnub_set_uuidmetadata_ex(pb, set_opts2); if (PNR_STARTED == result) { @@ -164,10 +164,10 @@ int main(void) { printf("Set channels' metadata\n"); struct pubnub_set_channelmetadata_opts set_channel_opts = pubnub_set_channelmetadata_defopts(); - set_channel_opts.data.name = "\"my_channel_name\""; - set_channel_opts.data.description = "\"my_channel_description\""; + set_channel_opts.data.name = "my_channel_name"; + set_channel_opts.data.description = "my_channel_description"; set_channel_opts.data.custom = "{\"key\":\"value\"}"; - set_channel_opts.include = "\"custom\""; + set_channel_opts.include = "custom"; result = pubnub_set_channelmetadata_ex(pb, "channel_id", set_channel_opts); From e1c77ca9438cf2a8227a20069e9eb0d663ec221e Mon Sep 17 00:00:00 2001 From: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:26:30 +0000 Subject: [PATCH 8/8] PubNub SDK v4.12.0 release. --- .pubnub.yml | 25 +++++++++++++++++-------- CHANGELOG.md | 10 ++++++++++ core/pubnub_version_internal.h | 2 +- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.pubnub.yml b/.pubnub.yml index 960f5650..12685d14 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,8 +1,17 @@ name: c-core schema: 1 -version: "4.11.2" +version: "4.12.0" scm: github.com/pubnub/c-core changelog: + - date: 2024-07-29 + version: v4.12.0 + changes: + - type: feature + text: "Added `filter` and `sort` parameters to be closer to the other SDKs with object API." + - type: feature + text: "Configurable `bool` type." + - type: bug + text: "Missing features needed for grant token API in CMakeLIsts.txt." - date: 2024-07-15 version: v4.11.2 changes: @@ -819,7 +828,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -885,7 +894,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -951,7 +960,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -1013,7 +1022,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -1074,7 +1083,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -1130,7 +1139,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" @@ -1183,7 +1192,7 @@ sdks: distribution-type: source code distribution-repository: GitHub release package-name: C-Core - location: https://github.com/pubnub/c-core/releases/tag/v4.11.2 + location: https://github.com/pubnub/c-core/releases/tag/v4.12.0 requires: - name: "miniz" diff --git a/CHANGELOG.md b/CHANGELOG.md index de74cc3c..e20502db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.12.0 +July 29 2024 + +#### Added +- Added `filter` and `sort` parameters to be closer to the other SDKs with object API. +- Configurable `bool` type. + +#### Fixed +- Missing features needed for grant token API in CMakeLIsts.txt. + ## v4.11.2 July 15 2024 diff --git a/core/pubnub_version_internal.h b/core/pubnub_version_internal.h index c393fdd6..506e9917 100644 --- a/core/pubnub_version_internal.h +++ b/core/pubnub_version_internal.h @@ -3,7 +3,7 @@ #define INC_PUBNUB_VERSION_INTERNAL -#define PUBNUB_SDK_VERSION "4.11.2" +#define PUBNUB_SDK_VERSION "4.12.0" #endif /* !defined INC_PUBNUB_VERSION_INTERNAL */