From 2566eba783842d9e285c4a8e21bf285b9ae5019c Mon Sep 17 00:00:00 2001 From: chao <48119764+withchao@users.noreply.github.com> Date: Thu, 16 May 2024 15:05:19 +0800 Subject: [PATCH 01/69] feat: use an optimized toolkit (#543) * fix: GroupApplicationAcceptedNotification * fix: GroupApplicationAcceptedNotification * package name replacement * friend hash --- .github/workflows/auto-invite.yml | 2 +- .golangci.yml | 4 +- .goreleaser.yaml | 2 +- CHANGELOG/.chglog/config.yml | 2 +- CHANGELOG/CHANGELOG-1.0.md | 16 ++-- CHANGELOG/CHANGELOG-2.0.md | 30 ++++---- CHANGELOG/CHANGELOG-2.1.md | 2 +- CHANGELOG/CHANGELOG-2.2.md | 2 +- CHANGELOG/CHANGELOG-2.3.md | 6 +- CHANGELOG/CHANGELOG-2.9.md | 14 ++-- CHANGELOG/CHANGELOG-3.0.md | 48 ++++++------ CHANGELOG/CHANGELOG.md | 2 +- CONTRIBUTING.md | 54 ++++++------- Makefile | 4 +- README.md | 52 ++++++------- README_zh-CN.md | 8 +- cmd/gordon_main.go | 2 +- cmd/press_open_im.go | 2 +- cmd/reliability_open_im.go | 2 +- cmd/sk_main.go | 2 +- docs/contrib/git_workflow.md | 6 +- go.mod | 36 ++++----- go.sum | 76 ++++++++++--------- internal/business/business.go | 4 +- internal/common/common.go | 2 +- internal/conversation_msg/conversation.go | 8 +- internal/conversation_msg/conversation_msg.go | 8 +- .../conversation_notification.go | 8 +- internal/conversation_msg/convert.go | 2 +- internal/conversation_msg/create_message.go | 2 +- internal/conversation_msg/delete.go | 6 +- internal/conversation_msg/entering.go | 12 +-- internal/conversation_msg/image.go | 6 +- internal/conversation_msg/message_check.go | 10 +-- .../conversation_msg/message_controller.go | 4 +- internal/conversation_msg/progress.go | 2 +- internal/conversation_msg/read_drawing.go | 10 +-- internal/conversation_msg/revoke.go | 10 +-- internal/conversation_msg/sdk.go | 10 +-- internal/conversation_msg/sync.go | 6 +- internal/file/upload.go | 10 +-- internal/friend/conversion.go | 2 +- internal/friend/friend.go | 4 +- internal/friend/hash.go | 33 ++++++++ internal/friend/sdk.go | 16 ++-- internal/friend/sync.go | 36 +++++++-- internal/full/open_im_sdk_full.go | 4 +- internal/group/conversion.go | 2 +- internal/group/group.go | 14 ++-- internal/group/notification.go | 4 +- internal/group/sdk.go | 54 ++++++++++--- internal/group/sync.go | 12 +-- internal/interaction/context.go | 2 +- internal/interaction/long_conn_mgr.go | 17 ++--- internal/interaction/msg_sync.go | 4 +- internal/interaction/ws_js.go | 2 +- internal/interaction/ws_resp_asyn.go | 2 +- internal/third/log.go | 2 +- internal/third/third.go | 2 +- internal/user/convert.go | 4 +- internal/user/sdk.go | 6 +- internal/user/sync.go | 6 +- internal/user/user.go | 14 ++-- internal/util/post.go | 18 ++--- internal/work_moments/work_moments.go | 2 +- msgtest/message_test.go | 2 +- msgtest/module/api_msg_sender.go | 4 +- msgtest/module/friend_manager.go | 2 +- msgtest/module/group_manager.go | 4 +- msgtest/module/manager.go | 8 +- msgtest/module/msg_sender.go | 6 +- msgtest/module/user_manager.go | 4 +- msgtest/pressure_test.go | 2 +- msgtest/sdk_user_simulator/listener.go | 2 + msgtest/sdk_user_simulator/user.go | 11 +-- open_im_sdk/apicb.go | 10 +-- open_im_sdk/caller.go | 18 ++--- open_im_sdk/em.go | 2 +- open_im_sdk/init_login.go | 7 +- open_im_sdk/userRelated.go | 8 +- open_im_sdk_callback/callback_go_sdk.go | 2 +- pkg/ccontext/context.go | 2 +- pkg/common/trigger_channel.go | 4 +- pkg/constant/server_api_router.go | 2 + pkg/db/chat_log_model_v3.go | 2 +- pkg/db/conversation_model.go | 4 +- pkg/db/db_init.go | 2 +- pkg/db/upload_model.go | 2 +- pkg/sdk_params_callback/friend_sdk_struct.go | 2 +- pkg/sdk_params_callback/group_sdk_struct.go | 6 +- pkg/sdkerrs/error.go | 7 +- pkg/sdkerrs/predefine.go | 2 +- pkg/server_api_params/auth_api_struct.go | 2 +- pkg/server_api_params/friend_api_struct.go | 2 +- pkg/server_api_params/group_api_struct.go | 2 +- pkg/server_api_params/user_api_struct.go | 2 +- pkg/syncer/syncer.go | 2 +- scripts/template/head.md.tmpl | 4 +- sdk_struct/sdk_struct.go | 2 +- test/account.go | 8 +- test/login.go | 2 +- test/reliability.go | 2 +- test/sendMessage.go | 4 +- test/t_conversation_msg.go | 6 +- test/t_friend_sdk.go | 6 +- test/t_group_sdk.go | 2 +- test/t_signaling.go | 2 +- test/work_group_create.go | 4 +- testv2/config.go | 2 +- testv2/empty_test.go | 2 +- testv2/friend_test.go | 4 +- testv2/group_test.go | 6 +- testv2/init.go | 4 +- testv2/listener.go | 2 + testv2/user_test.go | 6 +- wasm/event_listener/caller.go | 2 +- wasm/exec/executor.go | 4 +- 117 files changed, 539 insertions(+), 428 deletions(-) create mode 100644 internal/friend/hash.go diff --git a/.github/workflows/auto-invite.yml b/.github/workflows/auto-invite.yml index 40433ef5f..f37271f1e 100644 --- a/.github/workflows/auto-invite.yml +++ b/.github/workflows/auto-invite.yml @@ -41,7 +41,7 @@ jobs: + We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [👀 Open-IM-Server slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel. + Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email. + Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with Open-IM-Server projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information. - + Add [Wechat](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible. + + Add [Wechat](https://github.com/openimsdk/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible. - name: Close Issue uses: peter-evans/close-issue@v3 diff --git a/.golangci.yml b/.golangci.yml index 7d1c82d6d..774fe29ad 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -176,7 +176,7 @@ linters-settings: # put imports beginning with prefix after 3rd-party packages; # only support one prefix # if not set, use goimports.local-prefixes - prefix: github.com/OpenIMSDK/openim-sdk-core + prefix: github.com/openimsdk/openim-sdk-core gocognit: # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity: 30 @@ -333,7 +333,7 @@ linters-settings: goimports: # put imports beginning with prefix after 3rd-party packages; # it's a comma-separated list of prefixes - local-prefixes: github.com/OpenIMSDK/openim-sdk-core + local-prefixes: github.com/openimsdk/openim-sdk-core golint: # minimal confidence for issues, default is 0.8 min-confidence: 0.9 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 6be41a5d4..3e443f5ce 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -155,7 +155,7 @@ nfpms: - openIM.wasm # Your app's vendor. vendor: OpenIMSDK - homepage: https://github.com/OpenIMSDK/openim-sdk-core + homepage: https://github.com/openimsdk/openim-sdk-core maintainer: kubbot description: |- Auto sync github labels diff --git a/CHANGELOG/.chglog/config.yml b/CHANGELOG/.chglog/config.yml index c11e987cc..290193082 100644 --- a/CHANGELOG/.chglog/config.yml +++ b/CHANGELOG/.chglog/config.yml @@ -17,7 +17,7 @@ style: github template: CHANGELOG.tpl.md info: title: CHANGELOG - repository_url: https://github.com/OpenIMSDK/openim-sdk-core + repository_url: https://github.com/openimsdk/openim-sdk-core options: tag_filter_pattern: '^v' sort: "date" diff --git a/CHANGELOG/CHANGELOG-1.0.md b/CHANGELOG/CHANGELOG-1.0.md index b8539a901..52983b359 100644 --- a/CHANGELOG/CHANGELOG-1.0.md +++ b/CHANGELOG/CHANGELOG-1.0.md @@ -32,11 +32,11 @@ ## v1.0.0 - 2021-10-28 -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.7...HEAD -[v1.0.7]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.6...v1.0.7 -[v1.0.6]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.5...v1.0.6 -[v1.0.5]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.4...v1.0.5 -[v1.0.4]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.3...v1.0.4 -[v1.0.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.2...v1.0.3 -[v1.0.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.1...v1.0.2 -[v1.0.1]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.0...v1.0.1 +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.7...HEAD +[v1.0.7]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.6...v1.0.7 +[v1.0.6]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.5...v1.0.6 +[v1.0.5]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.4...v1.0.5 +[v1.0.4]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.3...v1.0.4 +[v1.0.3]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.2...v1.0.3 +[v1.0.2]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.1...v1.0.2 +[v1.0.1]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.0...v1.0.1 diff --git a/CHANGELOG/CHANGELOG-2.0.md b/CHANGELOG/CHANGELOG-2.0.md index 4d9cb747c..76bef9093 100644 --- a/CHANGELOG/CHANGELOG-2.0.md +++ b/CHANGELOG/CHANGELOG-2.0.md @@ -75,18 +75,18 @@ ## v2.0.0 - 2022-02-23 -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.3...HEAD -[v2.3.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.2...v2.3.3 -[v2.3.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 -[v2.3.0-rc0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.2.0...v2.3.0-rc0 -[v2.2.0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.1.0...v2.2.0 -[v2.1.0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.9...v2.1.0 -[v2.0.9]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.8...v2.0.9 -[v2.0.8]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.7...v2.0.8 -[v2.0.7]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.6...v2.0.7 -[v2.0.6]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.5...v2.0.6 -[v2.0.5]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.4...v2.0.5 -[v2.0.4]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.3...v2.0.4 -[v2.0.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.2...v2.0.3 -[v2.0.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.1...v2.0.2 -[v2.0.1]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.0...v2.0.1 +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.3...HEAD +[v2.3.3]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.2...v2.3.3 +[v2.3.2]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 +[v2.3.0-rc0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.2.0...v2.3.0-rc0 +[v2.2.0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.1.0...v2.2.0 +[v2.1.0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.9...v2.1.0 +[v2.0.9]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.8...v2.0.9 +[v2.0.8]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.7...v2.0.8 +[v2.0.7]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.6...v2.0.7 +[v2.0.6]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.5...v2.0.6 +[v2.0.5]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.4...v2.0.5 +[v2.0.4]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.3...v2.0.4 +[v2.0.3]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.2...v2.0.3 +[v2.0.2]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.1...v2.0.2 +[v2.0.1]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.0...v2.0.1 diff --git a/CHANGELOG/CHANGELOG-2.1.md b/CHANGELOG/CHANGELOG-2.1.md index 9a21ae247..83a4cda9d 100644 --- a/CHANGELOG/CHANGELOG-2.1.md +++ b/CHANGELOG/CHANGELOG-2.1.md @@ -20,4 +20,4 @@ - Merge branch 'tuoyun' -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.1.0...HEAD +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v2.1.0...HEAD diff --git a/CHANGELOG/CHANGELOG-2.2.md b/CHANGELOG/CHANGELOG-2.2.md index 42a0c8927..7cd31b116 100644 --- a/CHANGELOG/CHANGELOG-2.2.md +++ b/CHANGELOG/CHANGELOG-2.2.md @@ -21,4 +21,4 @@ - Merge branch 'tuoyun' -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.2.0...HEAD +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v2.2.0...HEAD diff --git a/CHANGELOG/CHANGELOG-2.3.md b/CHANGELOG/CHANGELOG-2.3.md index 9b06d6d0f..77833bf47 100644 --- a/CHANGELOG/CHANGELOG-2.3.md +++ b/CHANGELOG/CHANGELOG-2.3.md @@ -27,6 +27,6 @@ - Merge branch 'tuoyun' -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.3...HEAD -[v2.3.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.2...v2.3.3 -[v2.3.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.3...HEAD +[v2.3.3]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.2...v2.3.3 +[v2.3.2]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 diff --git a/CHANGELOG/CHANGELOG-2.9.md b/CHANGELOG/CHANGELOG-2.9.md index b51212ba8..1463f52dc 100644 --- a/CHANGELOG/CHANGELOG-2.9.md +++ b/CHANGELOG/CHANGELOG-2.9.md @@ -38,15 +38,15 @@ ## v2.9.0 - 2023-07-04 ### Reverts -- update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206)) +- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/Open-IM-Server/issues/206)) ### Pull Requests - Merge branch 'tuoyun' -[Unreleased]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+1.839643f...HEAD -[v2.9.0+1.839643f]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+2.35f07fe...v2.9.0+1.839643f -[v2.9.0+2.35f07fe]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+1.b5072b1...v2.9.0+2.35f07fe -[v2.9.0+1.b5072b1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+3.2667a3a...v2.9.0+1.b5072b1 -[v2.9.0+3.2667a3a]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0+7.04818ca...v2.9.0+3.2667a3a -[v2.9.0+7.04818ca]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v2.9.0...v2.9.0+7.04818ca +[Unreleased]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0+1.839643f...HEAD +[v2.9.0+1.839643f]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0+2.35f07fe...v2.9.0+1.839643f +[v2.9.0+2.35f07fe]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0+1.b5072b1...v2.9.0+2.35f07fe +[v2.9.0+1.b5072b1]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0+3.2667a3a...v2.9.0+1.b5072b1 +[v2.9.0+3.2667a3a]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0+7.04818ca...v2.9.0+3.2667a3a +[v2.9.0+7.04818ca]: https://github.com/openimsdk/Open-IM-Server/compare/v2.9.0...v2.9.0+7.04818ca diff --git a/CHANGELOG/CHANGELOG-3.0.md b/CHANGELOG/CHANGELOG-3.0.md index 6f342f515..4b1279302 100644 --- a/CHANGELOG/CHANGELOG-3.0.md +++ b/CHANGELOG/CHANGELOG-3.0.md @@ -102,27 +102,27 @@ ## v1.0.0 - 2021-10-28 -[Unreleased]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v3.0.0-rc.1...HEAD -[v3.0.0-rc.1]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.3...v3.0.0-rc.1 -[v2.3.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.2...v2.3.3 -[v2.3.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 -[v2.3.0-rc0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.2.0...v2.3.0-rc0 -[v2.2.0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.1.0...v2.2.0 -[v2.1.0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.9...v2.1.0 -[v2.0.9]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.8...v2.0.9 -[v2.0.8]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.7...v2.0.8 -[v2.0.7]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.6...v2.0.7 -[v2.0.6]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.5...v2.0.6 -[v2.0.5]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.4...v2.0.5 -[v2.0.4]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.3...v2.0.4 -[v2.0.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.2...v2.0.3 -[v2.0.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.1...v2.0.2 -[v2.0.1]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v2.0.0...v2.0.1 -[v2.0.0]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.7...v2.0.0 -[v1.0.7]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.6...v1.0.7 -[v1.0.6]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.5...v1.0.6 -[v1.0.5]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.4...v1.0.5 -[v1.0.4]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.3...v1.0.4 -[v1.0.3]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.2...v1.0.3 -[v1.0.2]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.1...v1.0.2 -[v1.0.1]: https://github.com/OpenIMSDK/openim-sdk-core/compare/v1.0.0...v1.0.1 +[Unreleased]: https://github.com/openimsdk/openim-sdk-core/compare/v3.0.0-rc.1...HEAD +[v3.0.0-rc.1]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.3...v3.0.0-rc.1 +[v2.3.3]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.2...v2.3.3 +[v2.3.2]: https://github.com/openimsdk/openim-sdk-core/compare/v2.3.0-rc0...v2.3.2 +[v2.3.0-rc0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.2.0...v2.3.0-rc0 +[v2.2.0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.1.0...v2.2.0 +[v2.1.0]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.9...v2.1.0 +[v2.0.9]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.8...v2.0.9 +[v2.0.8]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.7...v2.0.8 +[v2.0.7]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.6...v2.0.7 +[v2.0.6]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.5...v2.0.6 +[v2.0.5]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.4...v2.0.5 +[v2.0.4]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.3...v2.0.4 +[v2.0.3]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.2...v2.0.3 +[v2.0.2]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.1...v2.0.2 +[v2.0.1]: https://github.com/openimsdk/openim-sdk-core/compare/v2.0.0...v2.0.1 +[v2.0.0]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.7...v2.0.0 +[v1.0.7]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.6...v1.0.7 +[v1.0.6]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.5...v1.0.6 +[v1.0.5]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.4...v1.0.5 +[v1.0.4]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.3...v1.0.4 +[v1.0.3]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.2...v1.0.3 +[v1.0.2]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.1...v1.0.2 +[v1.0.1]: https://github.com/openimsdk/openim-sdk-core/compare/v1.0.0...v1.0.1 diff --git a/CHANGELOG/CHANGELOG.md b/CHANGELOG/CHANGELOG.md index 2d788d4c4..b9bafd1a1 100644 --- a/CHANGELOG/CHANGELOG.md +++ b/CHANGELOG/CHANGELOG.md @@ -13,7 +13,7 @@ All notable changes to this project will be documented in this file. -+ [https://github.com/OpenIMSDK/Open-IM-Server/releases](https://github.com/OpenIMSDK/Open-IM-Server/releases) ++ [https://github.com/openimsdk/Open-IM-Server/releases](https://github.com/openimsdk/Open-IM-Server/releases) ## command diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d63f6ce67..b42bdbaed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ The [Makefile](./Makefile) is for every developer, even if you don't know how to #### Code and doc contribution -Every action to make project OpenIM better is encouraged. On GitHub, every improvement for OpenIM could be via a [PR](https://github.com/OpenIMSDK/openim-sdk-core/pulls) (short for pull request). +Every action to make project OpenIM better is encouraged. On GitHub, every improvement for OpenIM could be via a [PR](https://github.com/openimsdk/openim-sdk-core/pulls) (short for pull request). + If you find a typo, try to fix it! + If you find a bug, try to fix it! @@ -49,22 +49,22 @@ Every action to make project OpenIM better is encouraged. On GitHub, every impro #### Where should I start? -Getting good at GitHub is the first step, we have a [list of labes](https://github.com/OpenIMSDK/openim-sdk-core/labels) and reading some of the [common tags](https://github.com/OpenIMSDK/openim-sdk-core/labels?sort=count-desc) helps us get involved in the community quickly.GitHub allows you to filter out types of issues and pull requests, which helps you discover items in need of triaging. This table includes some predetermined searches for convenience: +Getting good at GitHub is the first step, we have a [list of labes](https://github.com/openimsdk/openim-sdk-core/labels) and reading some of the [common tags](https://github.com/openimsdk/openim-sdk-core/labels?sort=count-desc) helps us get involved in the community quickly.GitHub allows you to filter out types of issues and pull requests, which helps you discover items in need of triaging. This table includes some predetermined searches for convenience: | Search | What it sorts | | ------------------------------------------------------------ | ------------------------------------------------------- | -| [created-asc](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acreated-asc) | Untriaged issues by age | -| [needs-triage](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+no%3Alabel) | Issues that need to be assigned to a Labels | -| [`is:open is:issue`](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aopen+is%3Aissue+sort%3Aupdated-desc) | Newest incoming issues | -| [comments-desc](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc) | Busiest untriaged issues, sorted by # of comments | -| [comments-asc](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-asc) | Issues that need more attention, based on # of comments | +| [created-asc](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acreated-asc) | Untriaged issues by age | +| [needs-triage](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+no%3Alabel) | Issues that need to be assigned to a Labels | +| [`is:open is:issue`](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aopen+is%3Aissue+sort%3Aupdated-desc) | Newest incoming issues | +| [comments-desc](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc) | Busiest untriaged issues, sorted by # of comments | +| [comments-asc](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-asc) | Issues that need more attention, based on # of comments | We suggest preparing your triage by filtering out the oldest, unlabelled issues and pull requests first. -1. If you are new to the project, don't know how to contribute OpenIM, please check out the [good first issue](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aopen+label%3A"good+first+issue"+sort%3Aupdated-desc) label and [help wanted](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aopen+is%3Aissue+label%3A"help+wanted"+sort%3Aupdated-desc). -2. You should be good at filtering the OpenIM issue tags and finding the ones you like, such as [RFC](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) for big initiatives, features for [feature](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+label%3Akind%2Ffeature+sort%3Aupdated-desc+) proposals, and [bug](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+label%3Akind%2Fbug+sort%3Aupdated-desc+) fixes. -3. If you are looking for something to work on, check out our [open issues](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). -4. If you have an idea for a new feature, please [open an issue](https://github.com/OpenIMSDK/openim-sdk-core/issues/new/choose), and we can discuss it. +1. If you are new to the project, don't know how to contribute OpenIM, please check out the [good first issue](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aopen+label%3A"good+first+issue"+sort%3Aupdated-desc) label and [help wanted](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aopen+is%3Aissue+label%3A"help+wanted"+sort%3Aupdated-desc). +2. You should be good at filtering the OpenIM issue tags and finding the ones you like, such as [RFC](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) for big initiatives, features for [feature](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+label%3Akind%2Ffeature+sort%3Aupdated-desc+) proposals, and [bug](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+label%3Akind%2Fbug+sort%3Aupdated-desc+) fixes. +3. If you are looking for something to work on, check out our [open issues](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). +4. If you have an idea for a new feature, please [open an issue](https://github.com/openimsdk/openim-sdk-core/issues/new/choose), and we can discuss it. > **Note** > Reply to `/assign` or `/assign @yourself` with a question you wish to resolve, and we'll assign the question to you and your name will be listed under `Assignees` @@ -73,7 +73,7 @@ We suggest preparing your triage by filtering out the oldest, unlabelled issues #### Design documents -For any substantial design, there should be a well-crafted design document. This document is not just a simple record, but also a detailed description and manifestation, which can help team members better understand the design thinking and grasp the design direction. In the process of writing the design document, we can choose to use tools such as `Google Docs` or `Notion`, and even mark **RFC** in [issues](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) or [discussions](https://github.com/OpenIMSDK/openim-sdk-core/discussions) for better collaboration. Of course, after completing the design document, we should also add it to our [Shared Drive](https://drive.google.com/drive/) and notify the appropriate working group to let everyone know of its existence. Only by doing so can we maximize the effectiveness of the design document and provide strong support for the smooth progress of the project. +For any substantial design, there should be a well-crafted design document. This document is not just a simple record, but also a detailed description and manifestation, which can help team members better understand the design thinking and grasp the design direction. In the process of writing the design document, we can choose to use tools such as `Google Docs` or `Notion`, and even mark **RFC** in [issues](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) or [discussions](https://github.com/openimsdk/openim-sdk-core/discussions) for better collaboration. Of course, after completing the design document, we should also add it to our [Shared Drive](https://drive.google.com/drive/) and notify the appropriate working group to let everyone know of its existence. Only by doing so can we maximize the effectiveness of the design document and provide strong support for the smooth progress of the project. Anybody can access the shared Drive for reading. To get access to comment. Once you've done that, head to the [shared Drive](https://drive.google.com/) and behold all the docs. @@ -104,10 +104,10 @@ To propose PR for the OpenIM item, we assume you have registered a GitHub ID. Th 2. **CLONE** your own repository to master locally. Use `git clone https://github.com//OpenIM.git` to clone repository to your local machine. Then you can create new branches to finish the change you wish to make. -3. **Set Remote** upstream to be `https://github.com/OpenIMSDK/openim-sdk-core.git` using the following two commands: +3. **Set Remote** upstream to be `https://github.com/openimsdk/openim-sdk-core.git` using the following two commands: ```bash - ❯ git remote add upstream https://github.com/OpenIMSDK/openim-sdk-core.git + ❯ git remote add upstream https://github.com/openimsdk/openim-sdk-core.git ❯ git remote set-url --push upstream no-pushing ``` @@ -117,7 +117,7 @@ To propose PR for the OpenIM item, we assume you have registered a GitHub ID. Th ❯ git remote -v origin https://github.com//OpenIM.git (fetch) origin https://github.com//OpenIM.git (push) - upstream https://github.com/OpenIMSDK/openim-sdk-core.git (fetch) + upstream https://github.com/openimsdk/openim-sdk-core.git (fetch) upstream no-pushing (push) ``` @@ -201,11 +201,11 @@ Instead we encourage you to send us a private email to 📮[winxu81@gmail.com](h #### Reporting general issues -To be honest, we regard every user of OpenIMas a very kind contributor. After experiencing OpenIM, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/OpenIMSDK/openim-sdk-core/issues/new/choose). +To be honest, we regard every user of OpenIMas a very kind contributor. After experiencing OpenIM, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/openimsdk/openim-sdk-core/issues/new/choose). Since we collaborate project OpenIM in a distributed way, we appreciate **WELL-WRITTEN**, **DETAILED**, **EXPLICIT** issue reports. To make the communication more efficient, we wish everyone could search if your issue is an existing one in the searching list. If you find it existing, please add your details in comments under the existing issue instead of opening a brand new one. -To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](https://github.com/OpenIMSDK/.github/tree/main/.github/ISSUE_TEMPLATE) for issue reporters. You can find three kinds of issue templates there: question, bug report and feature request. Please **BE SURE** to follow the instructions to fill fields in template. +To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](https://github.com/openimsdk/.github/tree/main/.github/ISSUE_TEMPLATE) for issue reporters. You can find three kinds of issue templates there: question, bug report and feature request. Please **BE SURE** to follow the instructions to fill fields in template. **There are a lot of cases when you could open an issue:** @@ -270,9 +270,9 @@ An example for this could be: #### PR Description -PR is the only way to make change to OpenIM project files. To help reviewers better get your purpose, **PR** description could not be too detailed. We encourage contributors to follow the [PR template](https://github.com/OpenIMSDK/.github/tree/main/.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request. +PR is the only way to make change to OpenIM project files. To help reviewers better get your purpose, **PR** description could not be too detailed. We encourage contributors to follow the [PR template](https://github.com/openimsdk/.github/tree/main/.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request. -You can find some very formal PR in [RFC](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) issues and learn about them. +You can find some very formal PR in [RFC](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) issues and learn about them. **📖 Opening PRs:** @@ -330,11 +330,11 @@ git() { #### CI actions -We host CI on [GitHub Actions](https://github.com/OpenIMSDK/openim-sdk-core/actions), we will make sure PR pass tests before we can merge it. +We host CI on [GitHub Actions](https://github.com/openimsdk/openim-sdk-core/actions), we will make sure PR pass tests before we can merge it. These two kind of tests: `lint` and `unit test` -`lint` tests if your code matches our code conventions, please consult [golangci-lint](https://golangci-lint.run/) and [lint config](https://github.com/OpenIMSDK/openim-sdk-core/blob/main/.golangci.yml) +`lint` tests if your code matches our code conventions, please consult [golangci-lint](https://golangci-lint.run/) and [lint config](https://github.com/openimsdk/openim-sdk-core/blob/main/.golangci.yml) > **Note** > @@ -354,9 +354,9 @@ Try your best to keep every function has been tested, it keeps the function beha **The documentation for OpenIM includes:** -+ [README.md](https://github.com/OpenIMSDK/openim-sdk-core/blob/main/README.md): This file includes the basic information and instructions for getting started with OpenIM. -+ [README_zh-CN.md](https://github.com/OpenIMSDK/openim-sdk-core/blob/main/README_zh-CN.md): This file includes the basic information and instructions for getting started with OpenIM in Chinese. -+ [CONTRIBUTING.md](https://github.com/OpenIMSDK/openim-sdk-core/blob/main/CONTRIBUTING.md): This file contains guidelines for contributing to OpenIM's codebase, such as how to submit issues, pull requests, and code reviews. ++ [README.md](https://github.com/openimsdk/openim-sdk-core/blob/main/README.md): This file includes the basic information and instructions for getting started with OpenIM. ++ [README_zh-CN.md](https://github.com/openimsdk/openim-sdk-core/blob/main/README_zh-CN.md): This file includes the basic information and instructions for getting started with OpenIM in Chinese. ++ [CONTRIBUTING.md](https://github.com/openimsdk/openim-sdk-core/blob/main/CONTRIBUTING.md): This file contains guidelines for contributing to OpenIM's codebase, such as how to submit issues, pull requests, and code reviews. + [Official Documentation](https://doc.rentsoft.cn): This is the official documentation for OpenIM, which includes comprehensive information on all of its features, configuration options, and troubleshooting tips. **Please obey the following rules to better format the docs, which would greatly improve the reading experience.** @@ -380,9 +380,9 @@ We integrated in the CICD actions [markdownlint](https://github.com/markdownlint We choose GitHub as the primary place for OpenIM to collaborate. So the latest updates of OpenIM are always here. Although contributions via **PR** is an explicit way to help, we still call for any other ways. -+ reply to other's [issues](https://github.com/OpenIMSDK/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) if you could; ++ reply to other's [issues](https://github.com/openimsdk/openim-sdk-core/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) if you could; + help solve other user's problems; -+ help review other's [PR](https://github.com/OpenIMSDK/openim-sdk-core/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc) design; ++ help review other's [PR](https://github.com/openimsdk/openim-sdk-core/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc) design; + discuss about OpenIM to make things clearer; + advocate [OpenIM](https://google.com/search?q=OpenIM) technology beyond GitHub; + write blogs on OpenIM and so on. @@ -430,6 +430,6 @@ In addition to Slack, we also offer the following ways to get in touch: + We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [👀 openim-sdk-core slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel. + Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email. + Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with openim-sdk-core projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information. -+ Add [Wechat](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of openim-sdk-core. We will process your request as soon as possible. ++ Add [Wechat](https://github.com/openimsdk/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of openim-sdk-core. We will process your request as soon as possible. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us. diff --git a/Makefile b/Makefile index 4ae5a57a2..57094e124 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # define the default goal # -ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-SDK-Core +ROOT_PACKAGE=github.com/openimsdk/Open-IM-SDK-Core # Copyright 2023 OpenIM. All rights reserved. # Use of this source code is governed by a MIT style @@ -156,7 +156,7 @@ ifeq (${BINS},) $(error Could not determine BINS, set ROOT_DIR or run in source dir) endif -EXCLUDE_TESTS=github.com/OpenIMSDK/openim-sdk-core/test +EXCLUDE_TESTS=github.com/openimsdk/openim-sdk-core/test # ============================================================================== # Build diff --git a/README.md b/README.md index a3252f491..c04d17a95 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@

-A+ -good first - +A+ +good first + - +

@@ -85,60 +85,60 @@ $ make deploy ## Contributing & Development -OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/OpenIMSDK/community). +OpenIM Our goal is to build a top-level open source community. We have a set of standards, in the [Community repository](https://github.com/openimsdk/community). -If you'd like to contribute to this openim-sdk-core repository, please read our [contributor documentation](https://github.com/OpenIMSDK/openim-sdk-core/blob/main/CONTRIBUTING.md). +If you'd like to contribute to this openim-sdk-core repository, please read our [contributor documentation](https://github.com/openimsdk/openim-sdk-core/blob/main/CONTRIBUTING.md). ## community meeting We welcome everyone to join us and contribute to openim-sdk-core, whether you are new to open source or professional. We are committed to promoting an open source culture, so we offer community members neighborhood prizes and reward money in recognition of their contributions. We believe that by working together, we can build a strong community and make valuable open source tools and resources available to more people. So if you are interested in openim-sdk-core, please join our community and start contributing your ideas and skills! -We take notes of each [biweekly meeting](https://github.com/OpenIMSDK/Open-IM-Server/issues/381) in [GitHub discussions](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting), and our minutes are written in [Google Docs](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing). +We take notes of each [biweekly meeting](https://github.com/openimsdk/Open-IM-Server/issues/381) in [GitHub discussions](https://github.com/openimsdk/Open-IM-Server/discussions/categories/meeting), and our minutes are written in [Google Docs](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing). -openim-sdk-core maintains a [public roadmap](https://github.com/OpenIMSDK/community/tree/main/roadmaps). It gives a a high-level view of the main priorities for the project, the maturity of different features and projects, and how to influence the project direction. +openim-sdk-core maintains a [public roadmap](https://github.com/openimsdk/community/tree/main/roadmaps). It gives a a high-level view of the main priorities for the project, the maturity of different features and projects, and how to influence the project direction. ## about OpenIM ### common -+ https://github.com/OpenIMSDK/automation: OpenIM Automation, cicd, and actions, Robotics. -+ https://github.com/OpenIMSDK/community: Community Management for OpenIM ++ https://github.com/openimsdk/automation: OpenIM Automation, cicd, and actions, Robotics. ++ https://github.com/openimsdk/community: Community Management for OpenIM ### OpenIM **Links** Contains some common parts of the OpenIM community. -+ https://github.com/OpenIMSDK/automation: OpenIM Automation, cicd, and actions, Robotics. -+ https://github.com/OpenIMSDK/openim-sdk-core: The IMSDK implemented by golang can be used in IOS, Android, PC and other platforms. -+ https://github.com/OpenIMSDK/openim-sdk-core: Instant messaging IM server. -+ https://github.com/OpenIMSDK/community: Community Management for OpenIM. ++ https://github.com/openimsdk/automation: OpenIM Automation, cicd, and actions, Robotics. ++ https://github.com/openimsdk/openim-sdk-core: The IMSDK implemented by golang can be used in IOS, Android, PC and other platforms. ++ https://github.com/openimsdk/openim-sdk-core: Instant messaging IM server. ++ https://github.com/openimsdk/community: Community Management for OpenIM. ### SDKs -+ [openim-sdk-core](https://github.com/OpenIMSDK/openim-sdk-core): A cross-platform SDK implemented in golang that can be used in IOS, Android, PC, and other platforms. -+ [Open-IM-SDK-iOS](https://github.com/OpenIMSDK/Open-IM-SDK-iOS): An iOS SDK generated based on openim-sdk-core, available for developers to reference. -+ [Open-IM-SDK-Android](https://github.com/OpenIMSDK/Open-IM-SDK-Android): An Android SDK generated based on openim-sdk-core, available for developers to reference. -+ [Open-IM-SDK-Flutter](https://github.com/OpenIMSDK/Open-IM-SDK-Flutter): A Flutter SDK generated based on Open-IM-SDK-iOS and Open-IM-SDK-Android, available for developers to reference. -+ [Open-IM-SDK-Uniapp](https://github.com/OpenIMSDK/Open-IM-SDK-Uniapp): A uni-app SDK generated based on Open-IM-SDK-iOS and Open-IM-SDK-Android, available for developers to reference. ++ [openim-sdk-core](https://github.com/openimsdk/openim-sdk-core): A cross-platform SDK implemented in golang that can be used in IOS, Android, PC, and other platforms. ++ [Open-IM-SDK-iOS](https://github.com/openimsdk/Open-IM-SDK-iOS): An iOS SDK generated based on openim-sdk-core, available for developers to reference. ++ [Open-IM-SDK-Android](https://github.com/openimsdk/Open-IM-SDK-Android): An Android SDK generated based on openim-sdk-core, available for developers to reference. ++ [Open-IM-SDK-Flutter](https://github.com/openimsdk/Open-IM-SDK-Flutter): A Flutter SDK generated based on Open-IM-SDK-iOS and Open-IM-SDK-Android, available for developers to reference. ++ [Open-IM-SDK-Uniapp](https://github.com/openimsdk/Open-IM-SDK-Uniapp): A uni-app SDK generated based on Open-IM-SDK-iOS and Open-IM-SDK-Android, available for developers to reference. ### Demos -+ [Open-IM-iOS-Demo](https://github.com/OpenIMSDK/Open-IM-iOS-Demo): An iOS demo based on Open-IM-SDK-iOS, available for developers to reference. -+ [Open-IM-Android-Demo](https://github.com/OpenIMSDK/Open-IM-Android-Demo): An Android demo based on Open-IM-SDK-Android, available for developers to reference. -+ [Open-IM-Flutter-Demo](https://github.com/OpenIMSDK/Open-IM-Flutter-Demo): A Flutter demo based on Open-IM-SDK-Flutter, available for developers to reference. ++ [Open-IM-iOS-Demo](https://github.com/openimsdk/Open-IM-iOS-Demo): An iOS demo based on Open-IM-SDK-iOS, available for developers to reference. ++ [Open-IM-Android-Demo](https://github.com/openimsdk/Open-IM-Android-Demo): An Android demo based on Open-IM-SDK-Android, available for developers to reference. ++ [Open-IM-Flutter-Demo](https://github.com/openimsdk/Open-IM-Flutter-Demo): A Flutter demo based on Open-IM-SDK-Flutter, available for developers to reference. ## Used By -OpenIM is used by the following companies ,let's write it down in [ADOPTER](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md). +OpenIM is used by the following companies ,let's write it down in [ADOPTER](https://github.com/openimsdk/community/blob/main/ADOPTERS.md). -Please leave your use cases in the comments [here](https://github.com/OpenIMSDK/Open-IM-Server/issues/379). +Please leave your use cases in the comments [here](https://github.com/openimsdk/Open-IM-Server/issues/379). ## License -[openim-sdk-core](https://github.com/OpenIMSDK/openim-sdk-core) is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/OpenIMSDK/openim-sdk-core/tree/main/LICENSE) for the full license text. +[openim-sdk-core](https://github.com/openimsdk/openim-sdk-core) is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/openimsdk/openim-sdk-core/tree/main/LICENSE) for the full license text. ## Thanks to our contributors! - + diff --git a/README_zh-CN.md b/README_zh-CN.md index a5bbfb2f6..3c7a22db4 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -8,11 +8,11 @@

-A+ -good first - +A+ +good first + - +

diff --git a/cmd/gordon_main.go b/cmd/gordon_main.go index 0d5349ec2..949e7a33b 100644 --- a/cmd/gordon_main.go +++ b/cmd/gordon_main.go @@ -18,11 +18,11 @@ import ( "context" "encoding/json" "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/network" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/test" + "github.com/openimsdk/tools/log" "time" ) diff --git a/cmd/press_open_im.go b/cmd/press_open_im.go index 5a8bf1e7d..bf52fc3a1 100644 --- a/cmd/press_open_im.go +++ b/cmd/press_open_im.go @@ -17,8 +17,8 @@ package main import ( "errors" "flag" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/test" + "github.com/openimsdk/tools/log" ) func main() { diff --git a/cmd/reliability_open_im.go b/cmd/reliability_open_im.go index a670a036c..07a15d6fb 100644 --- a/cmd/reliability_open_im.go +++ b/cmd/reliability_open_im.go @@ -17,8 +17,8 @@ package main import ( "errors" "flag" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/test" + "github.com/openimsdk/tools/log" ) func main() { diff --git a/cmd/sk_main.go b/cmd/sk_main.go index 18f7a7dab..b797984ac 100644 --- a/cmd/sk_main.go +++ b/cmd/sk_main.go @@ -16,10 +16,10 @@ package main import ( "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/db" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/test" + "github.com/openimsdk/tools/log" "time" ) diff --git a/docs/contrib/git_workflow.md b/docs/contrib/git_workflow.md index 22b658464..3b97b9590 100644 --- a/docs/contrib/git_workflow.md +++ b/docs/contrib/git_workflow.md @@ -18,7 +18,7 @@ OpenIM project uses the [GitHub flow](https://docs.github.com/en/get-started/qui ### Branch naming conventions -Every forked repository works independently, meaning that any contributor can create branches with the name they see fit. However, it is worth noting that OpenIM mirrors [OpenIM version skew policy](https://github.com/OpenIMSDK/openim-sdk-core/releases) by maintaining release branches for the most recent three minor releases. The only exception is that the main branch mirrors the latest OpenIM release (3.10) instead of using a `release-` prefixed one. +Every forked repository works independently, meaning that any contributor can create branches with the name they see fit. However, it is worth noting that OpenIM mirrors [OpenIM version skew policy](https://github.com/openimsdk/openim-sdk-core/releases) by maintaining release branches for the most recent three minor releases. The only exception is that the main branch mirrors the latest OpenIM release (3.10) instead of using a `release-` prefixed one. ```text main -------------------------------------------. (OpenIM 3.10) @@ -39,7 +39,7 @@ There are everyday tasks related to git that every contributor needs to perform, Creating a OpenIM fork, cloning it, and setting its upstream remote can be summarized on: -1. Visit +1. Visit 2. Click the `Fork` button (top right) to establish a cloud-based fork 3. Clone fork to local storage 4. Add to your fork OpenIM remote as upstream @@ -54,7 +54,7 @@ git clone https://github.com/$user/OpenIM.git ## Add OpenIM as upstream to your fork cd OpenIM -git remote add upstream https://github.com/OpenIMSDK/openim-sdk-core.git +git remote add upstream https://github.com/openimsdk/openim-sdk-core.git # or: git remote add upstream git@github.com:OpenIMSDK/openim-sdk-core.git ## Ensure to never push to upstream directly diff --git a/go.mod b/go.mod index 4910a6146..2f25f6d3e 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,43 @@ module github.com/openimsdk/openim-sdk-core/v3 -go 1.18 +go 1.21 + +toolchain go1.22.0 require ( - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/gorilla/websocket v1.4.2 - github.com/jinzhu/copier v0.3.5 + github.com/jinzhu/copier v0.4.0 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect github.com/pkg/errors v0.9.1 - google.golang.org/protobuf v1.31.0 // indirect - gorm.io/driver/sqlite v1.3.6 + google.golang.org/protobuf v1.33.0 // indirect + gorm.io/driver/sqlite v1.5.5 nhooyr.io/websocket v1.8.10 ) -require golang.org/x/net v0.19.0 +require golang.org/x/net v0.22.0 require ( - github.com/OpenIMSDK/protocol v0.0.45 - github.com/OpenIMSDK/tools v0.0.24 - github.com/google/go-cmp v0.5.9 + github.com/google/go-cmp v0.6.0 + github.com/openimsdk/protocol v0.0.66 + github.com/openimsdk/tools v0.0.49-alpha.9 github.com/patrickmn/go-cache v2.1.0+incompatible - golang.org/x/image v0.14.0 - gorm.io/gorm v1.23.8 + go.etcd.io/etcd/api/v3 v3.5.13 + golang.org/x/image v0.15.0 + gorm.io/gorm v1.25.10 ) require ( - github.com/bwmarrin/snowflake v0.3.0 // indirect + github.com/coreos/go-semver v0.3.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/lestrrat-go/strftime v1.0.6 // indirect - github.com/mattn/go-sqlite3 v1.14.12 // indirect - github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect - google.golang.org/grpc v1.56.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.62.1 // indirect ) diff --git a/go.sum b/go.sum index d43e428d6..1af3a2f24 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,25 @@ -github.com/OpenIMSDK/protocol v0.0.45 h1:0MxdGddw09k17xgR6Kn6ZLtcTrEosTCWXA/rhgSmbQQ= -github.com/OpenIMSDK/protocol v0.0.45/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= -github.com/OpenIMSDK/tools v0.0.24 h1:P8n7ZtsZEbm4W3dQAem29O+bigzy6YPXxFzd/D8Vh3U= -github.com/OpenIMSDK/tools v0.0.24/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= -github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4= @@ -32,8 +28,12 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/openimsdk/protocol v0.0.66 h1:AVYufQ+A7pQpemjaOtr62dwVa6Z2o6lN4d8erPch8NE= +github.com/openimsdk/protocol v0.0.66/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= +github.com/openimsdk/tools v0.0.49-alpha.9 h1:yoa3GS6t0d1mRv/S86niFBGDgSjy2EWWwBI5NAH1Kgk= +github.com/openimsdk/tools v0.0.49-alpha.9/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -42,36 +42,44 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.etcd.io/etcd/api/v3 v3.5.13 h1:8WXU2/NBge6AUF1K1gOexB6e07NgsN1hXK0rSTtgSp4= +go.etcd.io/etcd/api/v3 v3.5.13/go.mod h1:gBqlqkcMMZMVTMm4NDZloEVJzxQOQIls8splbqBDa0c= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= +gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= +gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= -gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo= +gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/internal/business/business.go b/internal/business/business.go index 614f6a7b4..ecc02cec9 100644 --- a/internal/business/business.go +++ b/internal/business/business.go @@ -21,9 +21,9 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) type Business struct { diff --git a/internal/common/common.go b/internal/common/common.go index 17da2935d..76250b5c0 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -17,8 +17,8 @@ package common import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/protocol/sdkws" "github.com/golang/protobuf/proto" + "github.com/openimsdk/protocol/sdkws" ) func UnmarshalTips(msg *sdkws.MsgData, detail proto.Message) error { diff --git a/internal/conversation_msg/conversation.go b/internal/conversation_msg/conversation.go index e949b4228..8fbbd1d20 100644 --- a/internal/conversation_msg/conversation.go +++ b/internal/conversation_msg/conversation.go @@ -33,12 +33,12 @@ import ( "github.com/jinzhu/copier" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" - "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" - pbConversation "github.com/OpenIMSDK/protocol/conversation" + pbConversation "github.com/openimsdk/protocol/conversation" ) func (c *Conversation) setConversation(ctx context.Context, apiReq *pbConversation.SetConversationsReq, localConversation *model_struct.LocalConversation) error { diff --git a/internal/conversation_msg/conversation_msg.go b/internal/conversation_msg/conversation_msg.go index b5b876b12..fbfbd5481 100644 --- a/internal/conversation_msg/conversation_msg.go +++ b/internal/conversation_msg/conversation_msg.go @@ -18,8 +18,6 @@ import ( "context" "encoding/json" "errors" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/openim-sdk-core/v3/internal/business" "github.com/openimsdk/openim-sdk-core/v3/internal/cache" "github.com/openimsdk/openim-sdk-core/v3/internal/file" @@ -37,6 +35,8 @@ import ( sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" @@ -992,7 +992,7 @@ func (c *Conversation) batchGetUserNameAndFaceURL(ctx context.Context, userIDs . log.ZWarn(ctx, "BatchGetUserNameAndFaceURL", err, "userIDs", userIDs) notInFriend = userIDs } else { - notInFriend = utils2.SliceSub(userIDs, utils2.Slice(friendList, func(e *model_struct.LocalFriend) string { + notInFriend = datautil.SliceSub(userIDs, datautil.Slice(friendList, func(e *model_struct.LocalFriend) string { return e.FriendUserID })) } @@ -1049,7 +1049,7 @@ func (c *Conversation) getUserNameAndFaceURL(ctx context.Context, userID string) return "", "", err } if len(users) == 0 { - return "", "", sdkerrs.ErrUserIDNotFound.Wrap(userID) + return "", "", sdkerrs.ErrUserIDNotFound.WrapMsg(userID) } c.user.UserBasicCache.Store(userID, &user.BasicInfo{FaceURL: users[0].FaceURL, Nickname: users[0].Nickname}) return users[0].FaceURL, users[0].Nickname, nil diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 2c7738bd0..a8c4e9e30 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -22,11 +22,11 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/utils/datautil" "time" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (c *Conversation) Work(c2v common.Cmd2Value) { @@ -680,7 +680,7 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { c.friend.DoNotification(ctx, v) } else if v.ContentType > constant.UserNotificationBegin && v.ContentType < constant.UserNotificationEnd { c.user.DoNotification(ctx, v) - } else if utils2.Contain(v.ContentType, constant.GroupApplicationRejectedNotification, constant.GroupApplicationAcceptedNotification, constant.JoinGroupApplicationNotification) { + } else if datautil.Contain(v.ContentType, constant.GroupApplicationRejectedNotification, constant.GroupApplicationAcceptedNotification, constant.JoinGroupApplicationNotification) { c.group.DoNotification(ctx, v) } else if v.ContentType > constant.SignalingNotificationBegin && v.ContentType < constant.SignalingNotificationEnd { diff --git a/internal/conversation_msg/convert.go b/internal/conversation_msg/convert.go index 535924086..78180d430 100644 --- a/internal/conversation_msg/convert.go +++ b/internal/conversation_msg/convert.go @@ -17,7 +17,7 @@ package conversation_msg import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - pbConversation "github.com/OpenIMSDK/protocol/conversation" + pbConversation "github.com/openimsdk/protocol/conversation" ) func ServerConversationToLocal(conversation *pbConversation.Conversation) *model_struct.LocalConversation { diff --git a/internal/conversation_msg/create_message.go b/internal/conversation_msg/create_message.go index db06d2fd9..ace457bea 100644 --- a/internal/conversation_msg/create_message.go +++ b/internal/conversation_msg/create_message.go @@ -17,8 +17,8 @@ package conversation_msg import ( "context" "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" diff --git a/internal/conversation_msg/delete.go b/internal/conversation_msg/delete.go index 982efc987..8cfa3e22c 100644 --- a/internal/conversation_msg/delete.go +++ b/internal/conversation_msg/delete.go @@ -24,10 +24,10 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - pbMsg "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" "github.com/jinzhu/copier" + pbMsg "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) // Delete the local and server diff --git a/internal/conversation_msg/entering.go b/internal/conversation_msg/entering.go index 2b0ecd299..5db1055e4 100644 --- a/internal/conversation_msg/entering.go +++ b/internal/conversation_msg/entering.go @@ -3,15 +3,15 @@ package conversation_msg import ( "context" "encoding/json" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/jinzhu/copier" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" "github.com/patrickmn/go-cache" "time" ) @@ -40,7 +40,7 @@ func newTyping(c *Conversation) *typing { e.platformIDSet[int32(id)] = struct{}{} e.platformIDs = append(e.platformIDs, int32(id)) } - utils2.Sort(e.platformIDs, true) + datautil.Sort(e.platformIDs, true) e.state.OnEvicted(func(key string, val interface{}) { var data inputStatesKey if err := json.Unmarshal([]byte(key), &data); err != nil { @@ -63,7 +63,7 @@ type typing struct { func (e *typing) ChangeInputStates(ctx context.Context, conversationID string, focus bool) error { if conversationID == "" { - return errs.ErrArgs.Wrap("conversationID can't be empty") + return errs.ErrArgs.WrapMsg("conversationID can't be empty") } conversation, err := e.conv.db.GetConversation(ctx, conversationID) if err != nil { diff --git a/internal/conversation_msg/image.go b/internal/conversation_msg/image.go index 4f87bb6f9..309776486 100644 --- a/internal/conversation_msg/image.go +++ b/internal/conversation_msg/image.go @@ -1,8 +1,8 @@ package conversation_msg import ( - "github.com/OpenIMSDK/tools/errs" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/errs" _ "golang.org/x/image/bmp" _ "golang.org/x/image/tiff" _ "golang.org/x/image/webp" @@ -16,7 +16,7 @@ import ( func getImageInfo(filePath string) (*sdk_struct.ImageInfo, error) { file, err := os.Open(filePath) if err != nil { - return nil, errs.Wrap(err, "image file open err") + return nil, errs.WrapMsg(err, "image file open err") } defer file.Close() info, err := file.Stat() @@ -25,7 +25,7 @@ func getImageInfo(filePath string) (*sdk_struct.ImageInfo, error) { } img, format, err := image.Decode(file) if err != nil { - return nil, errs.Wrap(err, "image file decode err") + return nil, errs.WrapMsg(err, "image file decode err") } size := img.Bounds().Max return &sdk_struct.ImageInfo{Width: int32(size.X), Height: int32(size.Y), Type: "image/" + format, Size: info.Size()}, nil diff --git a/internal/conversation_msg/message_check.go b/internal/conversation_msg/message_check.go index aa5cf086a..3dd820825 100644 --- a/internal/conversation_msg/message_check.go +++ b/internal/conversation_msg/message_check.go @@ -21,11 +21,11 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/utils/datautil" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" - "github.com/OpenIMSDK/protocol/sdkws" - utils2 "github.com/OpenIMSDK/tools/utils" + "github.com/openimsdk/protocol/sdkws" ) // 检测其内部连续性,如果不连续,则向前补齐,获取这一组消息的最大最小seq,以及需要补齐的seq列表长度 @@ -326,14 +326,14 @@ func (c *Conversation) singleHandle(ctx context.Context, self, others []*model_s } func (c *Conversation) groupHandle(ctx context.Context, self, others []*model_struct.LocalChatLog, lc *model_struct.LocalConversation) { allMessage := append(self, others...) - localGroupMemberInfo, err := c.group.GetSpecifiedGroupMembersInfo(ctx, lc.GroupID, utils2.Slice(allMessage, func(e *model_struct.LocalChatLog) string { + localGroupMemberInfo, err := c.group.GetSpecifiedGroupMembersInfo(ctx, lc.GroupID, datautil.Slice(allMessage, func(e *model_struct.LocalChatLog) string { return e.SendID })) if err != nil { log.ZError(ctx, "get group member info err", err) return } - groupMap := utils2.SliceToMap(localGroupMemberInfo, func(e *model_struct.LocalGroupMember) string { + groupMap := datautil.SliceToMap(localGroupMemberInfo, func(e *model_struct.LocalGroupMember) string { return e.UserID }) for _, chatLog := range allMessage { diff --git a/internal/conversation_msg/message_controller.go b/internal/conversation_msg/message_controller.go index 6d5195957..59678a3fb 100644 --- a/internal/conversation_msg/message_controller.go +++ b/internal/conversation_msg/message_controller.go @@ -25,8 +25,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) type MessageController struct { diff --git a/internal/conversation_msg/progress.go b/internal/conversation_msg/progress.go index dddc894d2..c19798231 100644 --- a/internal/conversation_msg/progress.go +++ b/internal/conversation_msg/progress.go @@ -21,7 +21,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) func NewUploadFileCallback(ctx context.Context, progress func(progress int), msg *sdk_struct.MsgStruct, conversationID string, db db_interface.DataBase) file.UploadFileCallback { diff --git a/internal/conversation_msg/read_drawing.go b/internal/conversation_msg/read_drawing.go index 61ff561c0..6b96d3147 100644 --- a/internal/conversation_msg/read_drawing.go +++ b/internal/conversation_msg/read_drawing.go @@ -18,7 +18,6 @@ import ( "context" "encoding/json" "errors" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -26,10 +25,11 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/utils/datautil" - pbMsg "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + pbMsg "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (c *Conversation) markMsgAsRead2Svr(ctx context.Context, conversationID string, seqs []int64) error { @@ -209,7 +209,7 @@ func (c *Conversation) doUnreadCount(ctx context.Context, conversation *model_st if err := json.Unmarshal([]byte(conversation.LatestMsg), latestMsg); err != nil { log.ZError(ctx, "Unmarshal err", err, "conversationID", conversation.ConversationID, "latestMsg", conversation.LatestMsg) } - if (!latestMsg.IsRead) && utils2.Contain(latestMsg.Seq, seqs...) { + if (!latestMsg.IsRead) && datautil.Contain(latestMsg.Seq, seqs...) { latestMsg.IsRead = true conversation.LatestMsg = utils.StructToJsonString(&latestMsg) _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{ConID: conversation.ConversationID, Action: constant.AddConOrUpLatMsg, Args: *conversation}, c.GetCh()) diff --git a/internal/conversation_msg/revoke.go b/internal/conversation_msg/revoke.go index 5e5a3b192..d2743a394 100644 --- a/internal/conversation_msg/revoke.go +++ b/internal/conversation_msg/revoke.go @@ -23,12 +23,12 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/utils/timeutil" - pbMsg "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/jinzhu/copier" + pbMsg "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (c *Conversation) doRevokeMsg(ctx context.Context, msg *sdkws.MsgData) { @@ -195,7 +195,7 @@ func (c *Conversation) revokeOneMessage(ctx context.Context, conversationID, cli ConversationID: conversationID, Seq: message.Seq, RevokerUserID: c.loginUserID, - RevokeTime: utils2.GetCurrentTimestampBySecond(), + RevokeTime: timeutil.GetCurrentTimestampBySecond(), SesstionType: conversation.ConversationType, ClientMsgID: clientMsgID, }) diff --git a/internal/conversation_msg/sdk.go b/internal/conversation_msg/sdk.go index 59b535b2f..cb0d06288 100644 --- a/internal/conversation_msg/sdk.go +++ b/internal/conversation_msg/sdk.go @@ -36,11 +36,11 @@ import ( "sync" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" - pbConversation "github.com/OpenIMSDK/protocol/conversation" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/protocol/wrapperspb" + pbConversation "github.com/openimsdk/protocol/conversation" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/protocol/wrapperspb" "github.com/jinzhu/copier" ) @@ -1107,7 +1107,7 @@ func (c *Conversation) GetMessageListReactionExtensions(ctx context.Context, con func (c *Conversation) SearchConversation(ctx context.Context, searchParam string) ([]*server_api_params.Conversation, error) { // Check if search parameter is empty if searchParam == "" { - return nil, sdkerrs.ErrArgs.Wrap("search parameter cannot be empty") + return nil, sdkerrs.ErrArgs.WrapMsg("search parameter cannot be empty") } // Perform the search in your database or data source diff --git a/internal/conversation_msg/sync.go b/internal/conversation_msg/sync.go index ca8ec86d6..b2a289605 100644 --- a/internal/conversation_msg/sync.go +++ b/internal/conversation_msg/sync.go @@ -16,14 +16,14 @@ package conversation_msg import ( "context" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" + "github.com/openimsdk/tools/utils/datautil" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) func (c *Conversation) SyncConversationsAndTriggerCallback(ctx context.Context, conversationsOnServer []*model_struct.LocalConversation) error { @@ -80,7 +80,7 @@ func (c *Conversation) SyncAllConversationHashReadSeqs(ctx context.Context) erro log.ZWarn(ctx, "get all conversations err", err) return err } - conversationsOnLocalMap := utils2.SliceToMap(conversationsOnLocal, func(e *model_struct.LocalConversation) string { + conversationsOnLocalMap := datautil.SliceToMap(conversationsOnLocal, func(e *model_struct.LocalConversation) string { return e.ConversationID }) for conversationID, v := range seqs { diff --git a/internal/file/upload.go b/internal/file/upload.go index b693a4ad0..4c9714e4d 100644 --- a/internal/file/upload.go +++ b/internal/file/upload.go @@ -21,11 +21,11 @@ import ( "encoding/hex" "errors" "fmt" - "github.com/OpenIMSDK/tools/errs" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/tools/errs" "io" "net/http" "net/url" @@ -34,8 +34,8 @@ import ( "sync/atomic" "time" - "github.com/OpenIMSDK/protocol/third" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/third" + "github.com/openimsdk/tools/log" ) type UploadFileReq struct { @@ -247,7 +247,7 @@ func (f *File) initiateMultipartUploadResp(ctx context.Context, req *third.Initi func (f *File) authSign(ctx context.Context, req *third.AuthSignReq) (*third.AuthSignResp, error) { if len(req.PartNumbers) == 0 { - return nil, errs.ErrArgs.Wrap("partNumbers is empty") + return nil, errs.ErrArgs.WrapMsg("partNumbers is empty") } return util.CallApi[third.AuthSignResp](ctx, constant.ObjectAuthSign, req) } @@ -412,7 +412,7 @@ func (u *UploadInfo) GetPartSign(ctx context.Context, partNumber int32) (*url.UR u.CreateTime = time.Now() index := u.getIndex(partNumber) if index < 0 { - return nil, nil, errs.ErrInternalServer.Wrap("server part sign invalid") + return nil, nil, errs.ErrInternalServer.WrapMsg("server part sign invalid") } return u.buildRequest(index) } diff --git a/internal/friend/conversion.go b/internal/friend/conversion.go index 52687e94f..0917f76cd 100644 --- a/internal/friend/conversion.go +++ b/internal/friend/conversion.go @@ -17,7 +17,7 @@ package friend import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func ServerFriendRequestToLocalFriendRequest(info *sdkws.FriendRequest) *model_struct.LocalFriendRequest { diff --git a/internal/friend/friend.go b/internal/friend/friend.go index 6c4056ad4..5aa850678 100644 --- a/internal/friend/friend.go +++ b/internal/friend/friend.go @@ -26,8 +26,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func NewFriend(loginUserID string, db db_interface.DataBase, user *user.User, conversationCh chan common.Cmd2Value) *Friend { diff --git a/internal/friend/hash.go b/internal/friend/hash.go new file mode 100644 index 000000000..7e5313802 --- /dev/null +++ b/internal/friend/hash.go @@ -0,0 +1,33 @@ +package friend + +import ( + "crypto/md5" + "encoding/binary" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/tools/utils/datautil" + "strconv" + "strings" +) + +func (f *Friend) CalculateHash(friends []*model_struct.LocalFriend) uint64 { + datautil.SortAny(friends, func(a, b *model_struct.LocalFriend) bool { + return a.CreateTime > b.CreateTime + }) + if len(friends) > constant.MaxSyncPullNumber { + friends = friends[:constant.MaxSyncPullNumber] + } + hashStr := strings.Join(datautil.Slice(friends, func(f *model_struct.LocalFriend) string { + return strings.Join([]string{ + f.FriendUserID, + f.Remark, + strconv.FormatInt(f.CreateTime, 10), + strconv.Itoa(int(f.AddSource)), + f.OperatorUserID, + f.Ex, + strconv.FormatBool(f.IsPinned), + }, ",") + }), ";") + sum := md5.Sum([]byte(hashStr)) + return binary.BigEndian.Uint64(sum[:]) +} diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index d1fd837a3..fcf345cf5 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -16,17 +16,17 @@ package friend import ( "context" - "github.com/OpenIMSDK/protocol/wrapperspb" - "github.com/OpenIMSDK/tools/errs" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" + "github.com/openimsdk/protocol/wrapperspb" + "github.com/openimsdk/tools/errs" - "github.com/OpenIMSDK/protocol/friend" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/friend" + "github.com/openimsdk/tools/log" ) func (f *Friend) GetSpecifiedFriendsInfo(ctx context.Context, friendUserIDList []string) ([]*server_api_params.FullUserInfo, error) { @@ -190,7 +190,7 @@ func (f *Friend) GetFriendListPage(ctx context.Context, offset, count int32) ([] func (f *Friend) SearchFriends(ctx context.Context, param *sdk.SearchFriendsParam) ([]*sdk.SearchFriendItem, error) { if len(param.KeywordList) == 0 || (!param.IsSearchNickname && !param.IsSearchUserID && !param.IsSearchRemark) { - return nil, sdkerrs.ErrArgs.Wrap("keyword is null or search field all false") + return nil, sdkerrs.ErrArgs.WrapMsg("keyword is null or search field all false") } localFriendList, err := f.db.SearchFriendList(ctx, param.KeywordList[0], param.IsSearchUserID, param.IsSearchNickname, param.IsSearchRemark) if err != nil { @@ -259,7 +259,7 @@ func (f *Friend) SetFriendsEx(ctx context.Context, friendIDs []string, ex string // Check if the specified ID is a friend friendResults, err := f.CheckFriend(ctx, friendIDs) if err != nil { - return errs.Wrap(err, "Error checking friend status") + return errs.WrapMsg(err, "Error checking friend status") } // Determine if friendID is indeed a friend @@ -277,7 +277,7 @@ func (f *Friend) SetFriendsEx(ctx context.Context, friendIDs []string, ex string // If this friendID is not a friend, return an error if !isFriend { - return errs.ErrRecordNotFound.Wrap("Not friend") + return errs.ErrRecordNotFound.WrapMsg("Not friend") } } @@ -286,7 +286,7 @@ func (f *Friend) SetFriendsEx(ctx context.Context, friendIDs []string, ex string updateErr := f.db.UpdateColumnsFriend(ctx, friendIDs, map[string]interface{}{"Ex": ex}) if updateErr != nil { - return errs.Wrap(updateErr, "Error updating friend information") + return errs.WrapMsg(updateErr, "Error updating friend information") } return nil } diff --git a/internal/friend/sync.go b/internal/friend/sync.go index 87a009af0..31bf27007 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -19,10 +19,10 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" - - "github.com/OpenIMSDK/protocol/friend" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + pconstant "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/protocol/friend" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (f *Friend) SyncBothFriendRequest(ctx context.Context, fromUserID, toUserID string) error { @@ -95,7 +95,7 @@ func (f *Friend) deleteFriend(ctx context.Context, friendUserID string) error { return err } if len(friends) == 0 { - return sdkerrs.ErrUserIDNotFound.Wrap("friendUserID not found") + return sdkerrs.ErrUserIDNotFound.WrapMsg("friendUserID not found") } if err := f.db.DeleteFriendDB(ctx, friendUserID); err != nil { return err @@ -117,6 +117,32 @@ func (f *Friend) SyncFriends(ctx context.Context, friendIDs []string) error { return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo), localData, nil) } +func (f *Friend) SyncFriendPart(ctx context.Context) error { + hashResp, err := util.CallApi[friend.GetFriendHashResp](ctx, constant.GetFriendHash, &friend.GetFriendHashReq{UserID: f.loginUserID}) + if err != nil { + return err + } + friends, err := f.db.GetAllFriendList(ctx) + if err != nil { + return err + } + hashCode := f.CalculateHash(friends) + log.ZDebug(ctx, "SyncFriendPart", "serverHash", hashResp.Hash, "serverTotal", hashResp.Total, "localHash", hashCode, "localTotal", len(friends)) + if hashCode == hashResp.Hash { + return nil + } + req := &friend.GetPaginationFriendsReq{ + UserID: f.loginUserID, + Pagination: &sdkws.RequestPagination{PageNumber: pconstant.FirstPageNumber, ShowNumber: pconstant.MaxSyncPullNumber}, + } + resp, err := util.CallApi[friend.GetPaginationFriendsResp](ctx, constant.GetFriendListRouter, req) + if err != nil { + return err + } + serverFriends := util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo) + return f.friendSyncer.Sync(ctx, serverFriends, friends, nil) +} + func (f *Friend) SyncAllBlackList(ctx context.Context) error { req := &friend.GetPaginationBlacksReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} fn := func(resp *friend.GetPaginationBlacksResp) []*sdkws.BlackInfo { return resp.Blacks } diff --git a/internal/full/open_im_sdk_full.go b/internal/full/open_im_sdk_full.go index 5af5471dd..ca26b5d6a 100644 --- a/internal/full/open_im_sdk_full.go +++ b/internal/full/open_im_sdk_full.go @@ -16,12 +16,12 @@ package full import ( "context" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" api "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (u *Full) GetUsersInfo(ctx context.Context, userIDs []string) ([]*api.FullUserInfo, error) { diff --git a/internal/group/conversion.go b/internal/group/conversion.go index 2bd851d89..27d7be6fd 100644 --- a/internal/group/conversion.go +++ b/internal/group/conversion.go @@ -17,7 +17,7 @@ package group import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func ServerGroupToLocalGroup(info *sdkws.GroupInfo) *model_struct.LocalGroup { diff --git a/internal/group/group.go b/internal/group/group.go index 150814d08..031cc15b6 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -16,10 +16,6 @@ package group import ( "context" - "github.com/OpenIMSDK/protocol/group" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" @@ -29,6 +25,10 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" ) func NewGroup(loginUserID string, db db_interface.DataBase, @@ -217,7 +217,7 @@ func (g *Group) GetGroupInfoFromLocal2Svr(ctx context.Context, groupID string) ( return nil, err } if len(svrGroup) == 0 { - return nil, sdkerrs.ErrGroupIDNotFound.Wrap("server not this group") + return nil, sdkerrs.ErrGroupIDNotFound.WrapMsg("server not this group") } return ServerGroupToLocalGroup(svrGroup[0]), nil } @@ -232,11 +232,11 @@ func (g *Group) GetGroupsInfoFromLocal2Svr(ctx context.Context, groupIDs ...stri return nil, err } var groupIDsNeedSync []string - localGroupIDs := utils2.Slice(groups, func(group *model_struct.LocalGroup) string { + localGroupIDs := datautil.Slice(groups, func(group *model_struct.LocalGroup) string { return group.GroupID }) for _, groupID := range groupIDs { - if !utils2.Contain(groupID, localGroupIDs...) { + if !datautil.Contain(groupID, localGroupIDs...) { groupIDsNeedSync = append(groupIDsNeedSync, groupID) } } diff --git a/internal/group/notification.go b/internal/group/notification.go index 79f5b3baf..f699ff13b 100644 --- a/internal/group/notification.go +++ b/internal/group/notification.go @@ -22,8 +22,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func (g *Group) DoNotification(ctx context.Context, msg *sdkws.MsgData) { diff --git a/internal/group/sdk.go b/internal/group/sdk.go index df3d0c538..b54c45323 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -16,6 +16,7 @@ package group import ( "context" + "github.com/openimsdk/tools/utils/datautil" "time" "github.com/openimsdk/openim-sdk-core/v3/internal/util" @@ -23,13 +24,12 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" + pconstant "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/tools/log" - "github.com/OpenIMSDK/tools/log" - - "github.com/OpenIMSDK/protocol/group" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/protocol/wrapperspb" - "github.com/OpenIMSDK/tools/utils" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/protocol/wrapperspb" ) // // deprecated use CreateGroup @@ -185,7 +185,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( if err != nil { return nil, err } - groupIDMap := utils.SliceSet(groupIDs) + groupIDMap := datautil.SliceSet(groupIDs) res := make([]*model_struct.LocalGroup, 0, len(groupIDs)) for i, v := range groupList { if _, ok := groupIDMap[v.GroupID]; ok { @@ -194,7 +194,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( } } if len(groupIDMap) > 0 { - groups, err := util.CallApi[group.GetGroupsInfoResp](ctx, constant.GetGroupsInfoRouter, &group.GetGroupsInfoReq{GroupIDs: utils.Keys(groupIDMap)}) + groups, err := util.CallApi[group.GetGroupsInfoResp](ctx, constant.GetGroupsInfoRouter, &group.GetGroupsInfoReq{GroupIDs: datautil.Keys(groupIDMap)}) if err != nil { log.ZError(ctx, "Call GetGroupsInfoRouter", err) } @@ -210,7 +210,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.SearchGroupsParam) ([]*model_struct.LocalGroup, error) { if len(param.KeywordList) == 0 || (!param.IsSearchGroupName && !param.IsSearchGroupID) { - return nil, sdkerrs.ErrArgs.Wrap("keyword is null or search field all false") + return nil, sdkerrs.ErrArgs.WrapMsg("keyword is null or search field all false") } groups, err := g.db.GetAllGroupInfoByGroupIDOrGroupName(ctx, param.KeywordList[0], param.IsSearchGroupID, param.IsSearchGroupName) // todo param.KeywordList[0] if err != nil { @@ -346,3 +346,39 @@ func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { } return false, nil } + +func (g *Group) SearchGroupMembersV2(ctx context.Context, req *group.SearchGroupMemberReq) ([]*model_struct.LocalGroupMember, error) { + if err := req.Check(); err != nil { + return nil, err + } + info, err := g.db.GetGroupInfoByGroupID(ctx, req.GroupID) + if err != nil { + return nil, err + } + if info.MemberCount <= pconstant.MaxSyncPullNumber { + return g.db.SearchGroupMembersDB(ctx, req.Keyword, req.GroupID, true, false, + int((req.Pagination.PageNumber-1)*req.Pagination.ShowNumber), int(req.Pagination.ShowNumber)) + } + resp, err := util.CallApi[group.SearchGroupMemberResp](ctx, constant.SearchGroupMember, req) + if err != nil { + return nil, err + } + return datautil.Slice(resp.Members, g.pbGroupMemberToLocal), nil +} + +func (g *Group) pbGroupMemberToLocal(pb *sdkws.GroupMemberFullInfo) *model_struct.LocalGroupMember { + return &model_struct.LocalGroupMember{ + GroupID: pb.GroupID, + UserID: pb.UserID, + Nickname: pb.Nickname, + FaceURL: pb.FaceURL, + RoleLevel: pb.RoleLevel, + JoinTime: pb.JoinTime, + JoinSource: pb.JoinSource, + InviterUserID: pb.InviterUserID, + MuteEndTime: pb.MuteEndTime, + OperatorUserID: pb.OperatorUserID, + Ex: pb.Ex, + //AttachedInfo: pb.AttachedInfo, + } +} diff --git a/internal/group/sync.go b/internal/group/sync.go index afeac3161..71dadc042 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -20,22 +20,22 @@ import ( "encoding/binary" "encoding/json" "errors" - "github.com/OpenIMSDK/protocol/group" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" - utils2 "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" "sync" ) func (g *Group) getGroupHash(members []*model_struct.LocalGroupMember) uint64 { - userIDs := utils2.Slice(members, func(member *model_struct.LocalGroupMember) string { + userIDs := datautil.Slice(members, func(member *model_struct.LocalGroupMember) string { return member.UserID }) - utils2.Sort(userIDs, true) + datautil.Sort(userIDs, true) memberMap := make(map[string]*sdkws.GroupMemberFullInfo) for _, member := range members { memberMap[member.UserID] = &sdkws.GroupMemberFullInfo{ diff --git a/internal/interaction/context.go b/internal/interaction/context.go index 841f5444a..9845010c1 100644 --- a/internal/interaction/context.go +++ b/internal/interaction/context.go @@ -17,7 +17,7 @@ package interaction import ( "time" - "github.com/OpenIMSDK/protocol/constant" + "github.com/openimsdk/protocol/constant" ) type ConnContext struct { diff --git a/internal/interaction/long_conn_mgr.go b/internal/interaction/long_conn_mgr.go index d437a343d..5869a8f2b 100644 --- a/internal/interaction/long_conn_mgr.go +++ b/internal/interaction/long_conn_mgr.go @@ -33,11 +33,11 @@ import ( "sync" "time" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" "github.com/golang/protobuf/proto" "github.com/gorilla/websocket" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" ) const ( @@ -369,7 +369,7 @@ func (c *LongConnMgr) writeBinaryMsgAndRetry(msg *GeneralWsReq) (chan *GeneralWs msgIncr, tempChan := c.Syncer.AddCh(msg.SendID) msg.MsgIncr = msgIncr if c.GetConnectionStatus() != Connected && msg.ReqIdentifier == constant.GetNewestSeq { - return tempChan, sdkerrs.ErrNetwork.Wrap("connection closed,conning...") + return tempChan, sdkerrs.ErrNetwork.WrapMsg("connection closed,conning...") } for i := 0; i < maxReconnectAttempts; i++ { err := c.writeBinaryMsg(*msg) @@ -383,7 +383,7 @@ func (c *LongConnMgr) writeBinaryMsgAndRetry(msg *GeneralWsReq) (chan *GeneralWs return tempChan, nil } } - return nil, sdkerrs.ErrNetwork.Wrap("send binary message error") + return nil, sdkerrs.ErrNetwork.WrapMsg("send binary message error") } func (c *LongConnMgr) writeBinaryMsg(req GeneralWsReq) error { @@ -394,7 +394,7 @@ func (c *LongConnMgr) writeBinaryMsg(req GeneralWsReq) error { return err } if c.GetConnectionStatus() != Connected { - return sdkerrs.ErrNetwork.Wrap("connection closed,re conning...") + return sdkerrs.ErrNetwork.WrapMsg("connection closed,re conning...") } _ = c.conn.SetWriteDeadline(writeWait) if c.IsCompression { @@ -527,12 +527,9 @@ func (c *LongConnMgr) reConn(ctx context.Context, num *int) (needRecon bool, err switch apiResp.ErrCode { case errs.TokenExpiredError, - errs.TokenInvalidError, errs.TokenMalformedError, errs.TokenNotValidYetError, - errs.TokenUnknownError, - errs.TokenNotExistError, - errs.TokenKickedError: + errs.TokenUnknownError: return false, err default: return true, err diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index e24e0b86a..42c39fc0a 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -22,8 +22,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "strings" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) const ( diff --git a/internal/interaction/ws_js.go b/internal/interaction/ws_js.go index 2b31f269c..1f2b243e4 100644 --- a/internal/interaction/ws_js.go +++ b/internal/interaction/ws_js.go @@ -22,7 +22,7 @@ import ( "context" "encoding/json" "fmt" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" "io" "net/http" "net/url" diff --git a/internal/interaction/ws_resp_asyn.go b/internal/interaction/ws_resp_asyn.go index d6018f5e5..b798cb06c 100644 --- a/internal/interaction/ws_resp_asyn.go +++ b/internal/interaction/ws_resp_asyn.go @@ -21,7 +21,7 @@ import ( "sync" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) type GeneralWsResp struct { diff --git a/internal/third/log.go b/internal/third/log.go index 756b132e4..aff0b6e82 100644 --- a/internal/third/log.go +++ b/internal/third/log.go @@ -4,11 +4,11 @@ import ( "context" "errors" "fmt" - "github.com/OpenIMSDK/protocol/third" "github.com/openimsdk/openim-sdk-core/v3/internal/file" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/protocol/third" "io" "math/rand" "os" diff --git a/internal/third/third.go b/internal/third/third.go index 7d7ae70a8..a7bf83545 100644 --- a/internal/third/third.go +++ b/internal/third/third.go @@ -16,9 +16,9 @@ package third import ( "context" - "github.com/OpenIMSDK/protocol/third" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/protocol/third" "github.com/openimsdk/openim-sdk-core/v3/internal/file" ) diff --git a/internal/user/convert.go b/internal/user/convert.go index 5993d3601..2f68844a3 100644 --- a/internal/user/convert.go +++ b/internal/user/convert.go @@ -15,10 +15,10 @@ package user import ( - "github.com/OpenIMSDK/protocol/user" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/protocol/user" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func ServerUserToLocalUser(user *sdkws.UserInfo) *model_struct.LocalUser { diff --git a/internal/user/sdk.go b/internal/user/sdk.go index 601a23e2a..6a97c913a 100644 --- a/internal/user/sdk.go +++ b/internal/user/sdk.go @@ -16,13 +16,13 @@ package user import ( "context" - pbUser "github.com/OpenIMSDK/protocol/user" - userPb "github.com/OpenIMSDK/protocol/user" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + pbUser "github.com/openimsdk/protocol/user" + userPb "github.com/openimsdk/protocol/user" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func (u *User) GetUsersInfo(ctx context.Context, userIDs []string) ([]*model_struct.LocalUser, error) { diff --git a/internal/user/sync.go b/internal/user/sync.go index 25de3b1b5..0eb5c186d 100644 --- a/internal/user/sync.go +++ b/internal/user/sync.go @@ -17,14 +17,14 @@ package user import ( "context" "errors" - userPb "github.com/OpenIMSDK/protocol/user" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + userPb "github.com/openimsdk/protocol/user" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" "gorm.io/gorm" ) diff --git a/internal/user/user.go b/internal/user/user.go index 00c5b41a6..0588a6dee 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -17,22 +17,22 @@ package user import ( "context" "fmt" - authPb "github.com/OpenIMSDK/protocol/auth" - "github.com/OpenIMSDK/protocol/sdkws" - userPb "github.com/OpenIMSDK/protocol/user" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/internal/cache" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" + authPb "github.com/openimsdk/protocol/auth" + "github.com/openimsdk/protocol/sdkws" + userPb "github.com/openimsdk/protocol/user" + "github.com/openimsdk/tools/log" - PbConstant "github.com/OpenIMSDK/protocol/constant" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + PbConstant "github.com/openimsdk/protocol/constant" ) type BasicInfo struct { @@ -260,7 +260,7 @@ func (u *User) userCommandUpdateNotification(ctx context.Context, msg *sdkws.Msg func (u *User) GetUsersInfoFromSvr(ctx context.Context, userIDs []string) ([]*model_struct.LocalUser, error) { resp, err := util.CallApi[userPb.GetDesignateUsersResp](ctx, constant.GetUsersInfoRouter, userPb.GetDesignateUsersReq{UserIDs: userIDs}) if err != nil { - return nil, sdkerrs.Warp(err, "GetUsersInfoFromSvr failed") + return nil, sdkerrs.WrapMsg(err, "GetUsersInfoFromSvr failed") } return util.Batch(ServerUserToLocalUser, resp.UsersInfo), nil } @@ -274,7 +274,7 @@ func (u *User) GetSingleUserFromSvr(ctx context.Context, userID string) (*model_ if len(users) > 0 { return users[0], nil } - return nil, sdkerrs.ErrUserIDNotFound.Wrap(fmt.Sprintf("getSelfUserInfo failed, userID: %s not exist", userID)) + return nil, sdkerrs.ErrUserIDNotFound.WrapMsg(fmt.Sprintf("getSelfUserInfo failed, userID: %s not exist", userID)) } // getSelfUserInfo retrieves the user's information. diff --git a/internal/util/post.go b/internal/util/post.go index fcf48b391..17a0004e1 100644 --- a/internal/util/post.go +++ b/internal/util/post.go @@ -25,8 +25,8 @@ import ( "net/http" "time" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) // apiClient is a global HTTP client with a timeout of one minute. @@ -54,7 +54,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { // Extract operationID from context and validate. operationID, _ := ctx.Value("operationID").(string) if operationID == "" { - err := sdkerrs.ErrArgs.Wrap("call api operationID is empty") + err := sdkerrs.ErrArgs.WrapMsg("call api operationID is empty") log.ZError(ctx, "ApiRequest", err, "type", "ctx not set operationID") return err } @@ -73,7 +73,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { reqBody, err := json.Marshal(req) if err != nil { log.ZError(ctx, "ApiRequest", err, "type", "json.Marshal(req) failed") - return sdkerrs.ErrSdkInternal.Wrap("json.Marshal(req) failed " + err.Error()) + return sdkerrs.ErrSdkInternal.WrapMsg("json.Marshal(req) failed " + err.Error()) } // Construct the full API URL and create a new HTTP request with context. @@ -82,7 +82,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { request, err := http.NewRequestWithContext(ctx, http.MethodPost, reqUrl, bytes.NewReader(reqBody)) if err != nil { log.ZError(ctx, "ApiRequest", err, "type", "http.NewRequestWithContext failed") - return sdkerrs.ErrSdkInternal.Wrap("sdk http.NewRequestWithContext failed " + err.Error()) + return sdkerrs.ErrSdkInternal.WrapMsg("sdk http.NewRequestWithContext failed " + err.Error()) } // Set headers for the request. @@ -96,7 +96,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { response, err := apiClient.Do(request) if err != nil { log.ZError(ctx, "ApiRequest", err, "type", "network error") - return sdkerrs.ErrNetwork.Wrap("ApiPost http.Client.Do failed " + err.Error()) + return sdkerrs.ErrNetwork.WrapMsg("ApiPost http.Client.Do failed " + err.Error()) } // Ensure the response body is closed after processing. @@ -106,7 +106,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { respBody, err := io.ReadAll(response.Body) if err != nil { log.ZError(ctx, "ApiResponse", err, "type", "read body", "status", response.Status) - return sdkerrs.ErrSdkInternal.Wrap("io.ReadAll(ApiResponse) failed " + err.Error()) + return sdkerrs.ErrSdkInternal.WrapMsg("io.ReadAll(ApiResponse) failed " + err.Error()) } // Log the response for debugging purposes. @@ -116,7 +116,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { var baseApi ApiResponse if err := json.Unmarshal(respBody, &baseApi); err != nil { log.ZError(ctx, "ApiResponse", err, "type", "api code parse") - return sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("api %s json.Unmarshal(%q, %T) failed %s", api, string(respBody), &baseApi, err.Error())) + return sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("api %s json.Unmarshal(%q, %T) failed %s", api, string(respBody), &baseApi, err.Error())) } // Check if the API returned an error code and handle it. @@ -135,7 +135,7 @@ func ApiPost(ctx context.Context, api string, req, resp any) (err error) { // Unmarshal the actual data part of the response into the provided response object. if err := json.Unmarshal(baseApi.Data, resp); err != nil { log.ZError(ctx, "ApiResponse", err, "type", "api data parse", "data", string(baseApi.Data), "bind", fmt.Sprintf("%T", resp)) - return sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("json.Unmarshal(%q, %T) failed %s", string(baseApi.Data), resp, err.Error())) + return sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("json.Unmarshal(%q, %T) failed %s", string(baseApi.Data), resp, err.Error())) } return nil diff --git a/internal/work_moments/work_moments.go b/internal/work_moments/work_moments.go index 2a38e45f8..2eacd31fe 100644 --- a/internal/work_moments/work_moments.go +++ b/internal/work_moments/work_moments.go @@ -21,7 +21,7 @@ package workMoments // "open_im_sdk/pkg/db/model_struct" // "open_im_sdk/pkg/utils" // -// "github.com/OpenIMSDK/tools/log" +// "github.com/openimsdk/tools/log" //) // //type WorkMoments struct { diff --git a/msgtest/message_test.go b/msgtest/message_test.go index 5ef1a2e78..f4f7c5755 100644 --- a/msgtest/message_test.go +++ b/msgtest/message_test.go @@ -2,11 +2,11 @@ package msgtest import ( "context" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/msgtest/module" "github.com/openimsdk/openim-sdk-core/v3/msgtest/sdk_user_simulator" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/log" "testing" ) diff --git a/msgtest/module/api_msg_sender.go b/msgtest/module/api_msg_sender.go index 4b46e62a5..d16596597 100644 --- a/msgtest/module/api_msg_sender.go +++ b/msgtest/module/api_msg_sender.go @@ -6,8 +6,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/protocol/sdkws" ) type ApiMsgSender struct { diff --git a/msgtest/module/friend_manager.go b/msgtest/module/friend_manager.go index 4f63b609b..2861f45e7 100644 --- a/msgtest/module/friend_manager.go +++ b/msgtest/module/friend_manager.go @@ -3,7 +3,7 @@ package module import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" - "github.com/OpenIMSDK/protocol/friend" + "github.com/openimsdk/protocol/friend" ) type TestFriendManager struct { diff --git a/msgtest/module/group_manager.go b/msgtest/module/group_manager.go index 22cf6bfcd..3dc9033cf 100644 --- a/msgtest/module/group_manager.go +++ b/msgtest/module/group_manager.go @@ -6,8 +6,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "time" - "github.com/OpenIMSDK/protocol/group" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" ) type TestGroupManager struct { diff --git a/msgtest/module/manager.go b/msgtest/module/manager.go index 4c18455cf..d99dcaf0f 100644 --- a/msgtest/module/manager.go +++ b/msgtest/module/manager.go @@ -5,14 +5,14 @@ import ( "context" "encoding/json" "fmt" - authPB "github.com/OpenIMSDK/protocol/auth" - "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/mcontext" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + authPB "github.com/openimsdk/protocol/auth" + "github.com/openimsdk/protocol/msg" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" "io" "net/http" ) diff --git a/msgtest/module/msg_sender.go b/msgtest/module/msg_sender.go index 7460b5e84..8878766ac 100644 --- a/msgtest/module/msg_sender.go +++ b/msgtest/module/msg_sender.go @@ -12,9 +12,9 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "time" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/mcontext" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" ) type SendMsgUser struct { diff --git a/msgtest/module/user_manager.go b/msgtest/module/user_manager.go index 2af08b957..da98bf40b 100644 --- a/msgtest/module/user_manager.go +++ b/msgtest/module/user_manager.go @@ -5,8 +5,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "time" - "github.com/OpenIMSDK/protocol/sdkws" - userPB "github.com/OpenIMSDK/protocol/user" + "github.com/openimsdk/protocol/sdkws" + userPB "github.com/openimsdk/protocol/user" ) type TestUserManager struct { diff --git a/msgtest/pressure_test.go b/msgtest/pressure_test.go index 835128c24..e0b1f229f 100644 --- a/msgtest/pressure_test.go +++ b/msgtest/pressure_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) const ( diff --git a/msgtest/sdk_user_simulator/listener.go b/msgtest/sdk_user_simulator/listener.go index 412ae384b..7f652ed51 100644 --- a/msgtest/sdk_user_simulator/listener.go +++ b/msgtest/sdk_user_simulator/listener.go @@ -210,6 +210,8 @@ func (testGroupListener) OnGroupDismissed(callbackInfo string) { type testConnListener struct { } +func (t *testConnListener) OnUserTokenInvalid(errMsg string) {} + func (t *testConnListener) OnUserTokenExpired() { } diff --git a/msgtest/sdk_user_simulator/user.go b/msgtest/sdk_user_simulator/user.go index e0c8a66b5..a92a1cc87 100644 --- a/msgtest/sdk_user_simulator/user.go +++ b/msgtest/sdk_user_simulator/user.go @@ -3,12 +3,13 @@ package sdk_user_simulator import ( "context" "fmt" - "github.com/OpenIMSDK/tools/log" - "github.com/openimsdk/openim-sdk-core/v3/internal/login" + "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/log" + "go.etcd.io/etcd/api/v3/version" ) var ( @@ -33,7 +34,7 @@ func GetRelativeServerTime() int64 { } func InitSDKAndLogin(userID, token string) error { - userForSDK := login.NewLoginMgr() + userForSDK := open_im_sdk.NewLoginMgr() var cf sdk_struct.IMConfig cf.ApiAddr = APIADDR cf.PlatformID = int32(PLATFORMID) @@ -45,7 +46,7 @@ func InitSDKAndLogin(userID, token string) error { cf.LogFilePath = "" var testConnListener testConnListener userForSDK.InitSDK(cf, &testConnListener) - if err := log.InitFromConfig(userID+"_open-im-sdk-core", "", int(LogLevel), true, false, cf.DataDir, 0, 24); err != nil { + if err := log.InitFromConfig(userID+"_open-im-sdk-core", "", int(LogLevel), true, false, cf.DataDir, 0, 24, version.Version); err != nil { return err } ctx := ccontext.WithOperationID(userForSDK.BaseCtx(), utils.OperationIDGenerator()) @@ -58,7 +59,7 @@ func InitSDKAndLogin(userID, token string) error { return nil } -func SetListener(userForSDK *login.LoginMgr, userID string) { +func SetListener(userForSDK *open_im_sdk.LoginMgr, userID string) { var testConversation conversationCallBack userForSDK.SetConversationListener(&testConversation) diff --git a/open_im_sdk/apicb.go b/open_im_sdk/apicb.go index 392eee1da..c36b3126b 100644 --- a/open_im_sdk/apicb.go +++ b/open_im_sdk/apicb.go @@ -2,10 +2,10 @@ package open_im_sdk import ( "context" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" "sync/atomic" ) @@ -36,18 +36,14 @@ func (c *apiErrCallback) OnError(ctx context.Context, err error) { _ = common.TriggerCmdLogOut(ctx, c.loginMgrCh) } case - errs.TokenInvalidError, errs.TokenMalformedError, errs.TokenNotValidYetError, - errs.TokenUnknownError, - errs.TokenNotExistError: + errs.TokenUnknownError: if atomic.CompareAndSwapInt32(&c.tokenInvalidState, 0, 1) { log.ZError(ctx, "OnUserTokenInvalid callback", err) c.listener.OnUserTokenInvalid(err.Error()) _ = common.TriggerCmdLogOut(ctx, c.loginMgrCh) } - - case errs.TokenKickedError: if atomic.CompareAndSwapInt32(&c.kickedOfflineState, 0, 1) { log.ZError(ctx, "OnKickedOffline callback", err) c.listener.OnKickedOffline() diff --git a/open_im_sdk/caller.go b/open_im_sdk/caller.go index f638b702a..484aa080f 100644 --- a/open_im_sdk/caller.go +++ b/open_im_sdk/caller.go @@ -27,9 +27,9 @@ import ( "runtime/debug" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" - "github.com/OpenIMSDK/tools/errs" + "github.com/openimsdk/tools/errs" ) func isNumeric(kind reflect.Kind) bool { @@ -91,10 +91,10 @@ func call_(operationID string, fn any, args ...any) (res any, err error) { funcPtr := reflect.ValueOf(fn).Pointer() funcName := runtime.FuncForPC(funcPtr).Name() if operationID == "" { - return nil, sdkerrs.ErrArgs.Wrap("call function operationID is empty") + return nil, sdkerrs.ErrArgs.WrapMsg("call function operationID is empty") } if err := CheckResourceLoad(UserForSDK, funcName); err != nil { - return nil, sdkerrs.ErrResourceLoad.Wrap("not load resource") + return nil, sdkerrs.ErrResourceLoad.WrapMsg("not load resource") } ctx := ccontext.WithOperationID(UserForSDK.BaseCtx(), operationID) defer func(start time.Time) { @@ -115,12 +115,12 @@ func call_(operationID string, fn any, args ...any) (res any, err error) { log.ZInfo(ctx, "func call req", "function name", funcName, "args", args) fnv := reflect.ValueOf(fn) if fnv.Kind() != reflect.Func { - return nil, sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("call function fn is not function, is %T", fn)) + return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("call function fn is not function, is %T", fn)) } fnt := fnv.Type() nin := fnt.NumIn() if len(args)+1 != nin { - return nil, sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("go code error: fn in args num is not match")) + return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go code error: fn in args num is not match")) } ins := make([]reflect.Value, 0, nin) ins = append(ins, reflect.ValueOf(ctx)) @@ -141,7 +141,7 @@ func call_(operationID string, fn any, args ...any) (res any, err error) { case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map: v := reflect.New(inFnField) if err := json.Unmarshal([]byte(args[i].(string)), v.Interface()); err != nil { - return nil, sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("go call json.Unmarshal error: %s", err)) + return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go call json.Unmarshal error: %s", err)) } if ptr == 0 { v = v.Elem() @@ -162,7 +162,7 @@ func call_(operationID string, fn any, args ...any) (res any, err error) { // ins = append(ins, reflect.ValueOf(v)) // continue //} - return nil, sdkerrs.ErrSdkInternal.Wrap(fmt.Sprintf("go code error: fn in args type is not match")) + return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go code error: fn in args type is not match")) } outs := fnv.Call(ins) if len(outs) == 0 { @@ -361,7 +361,7 @@ func messageCall_(callback open_im_sdk_callback.SendMsgCallBack, operationID str } }() if operationID == "" { - callback.OnError(sdkerrs.ArgsError, sdkerrs.ErrArgs.Wrap("operationID is empty").Error()) + callback.OnError(sdkerrs.ArgsError, sdkerrs.ErrArgs.WrapMsg("operationID is empty").Error()) return } if err := CheckResourceLoad(UserForSDK, ""); err != nil { diff --git a/open_im_sdk/em.go b/open_im_sdk/em.go index de39cd358..9ef80a8fd 100644 --- a/open_im_sdk/em.go +++ b/open_im_sdk/em.go @@ -17,8 +17,8 @@ package open_im_sdk import ( "context" "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" + "github.com/openimsdk/tools/log" ) var ErrNotImplemented = errors.New("not set listener") diff --git a/open_im_sdk/init_login.go b/open_im_sdk/init_login.go index 20bb1f79d..cb95e4675 100644 --- a/open_im_sdk/init_login.go +++ b/open_im_sdk/init_login.go @@ -22,10 +22,11 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "go.etcd.io/etcd/api/v3/version" "strings" - "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/mcontext" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mcontext" ) func GetSdkVersion() string { @@ -54,7 +55,7 @@ func InitSDK(listener open_im_sdk_callback.OnConnListener, operationID string, c if configArgs.PlatformID == 0 { return false } - if err := log.InitFromConfig("open-im-sdk-core", "", int(configArgs.LogLevel), configArgs.IsLogStandardOutput, false, configArgs.LogFilePath, rotateCount, rotationTime); err != nil { + if err := log.InitFromConfig("open-im-sdk-core", "", int(configArgs.LogLevel), configArgs.IsLogStandardOutput, false, configArgs.LogFilePath, rotateCount, rotationTime, version.Version); err != nil { fmt.Println(operationID, "log init failed ", err.Error()) } fmt.Println("init log success") diff --git a/open_im_sdk/userRelated.go b/open_im_sdk/userRelated.go index 9d77afae7..c4b6a366d 100644 --- a/open_im_sdk/userRelated.go +++ b/open_im_sdk/userRelated.go @@ -19,9 +19,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/OpenIMSDK/protocol/push" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/internal/business" conv "github.com/openimsdk/openim-sdk-core/v3/internal/conversation_msg" "github.com/openimsdk/openim-sdk-core/v3/internal/file" @@ -41,6 +38,9 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/protocol/push" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" "strings" "sync" "time" @@ -335,7 +335,7 @@ func (u *LoginMgr) login(ctx context.Context, userID, token string) error { var err error u.db, err = db.NewDataBase(ctx, userID, u.info.DataDir, int(u.info.LogLevel)) if err != nil { - return sdkerrs.ErrSdkInternal.Wrap("init database " + err.Error()) + return sdkerrs.ErrSdkInternal.WrapMsg("init database " + err.Error()) } u.checkSendingMessage(ctx) log.ZDebug(ctx, "NewDataBase ok", "userID", userID, "dataDir", u.info.DataDir, "login cost time", time.Since(t1)) diff --git a/open_im_sdk_callback/callback_go_sdk.go b/open_im_sdk_callback/callback_go_sdk.go index ad9d778b8..b38005e6d 100644 --- a/open_im_sdk_callback/callback_go_sdk.go +++ b/open_im_sdk_callback/callback_go_sdk.go @@ -19,7 +19,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) type OnFriendshipListenerSdk interface { diff --git a/pkg/ccontext/context.go b/pkg/ccontext/context.go index 7c012899d..67855a596 100644 --- a/pkg/ccontext/context.go +++ b/pkg/ccontext/context.go @@ -20,7 +20,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/tools/mcontext" + "github.com/openimsdk/tools/mcontext" ) const ( diff --git a/pkg/common/trigger_channel.go b/pkg/common/trigger_channel.go index 5d0ca4f0a..a0a4a89c1 100644 --- a/pkg/common/trigger_channel.go +++ b/pkg/common/trigger_channel.go @@ -22,9 +22,9 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func TriggerCmdJoinedSuperGroup(cmd sdk_struct.CmdJoinedSuperGroup, joinedSuperGroupCh chan Cmd2Value) error { diff --git a/pkg/constant/server_api_router.go b/pkg/constant/server_api_router.go index ae0875f10..269d7dd8c 100644 --- a/pkg/constant/server_api_router.go +++ b/pkg/constant/server_api_router.go @@ -45,6 +45,7 @@ const ( AddFriendResponse = "/friend/add_friend_response" SetFriendRemark = "/friend/set_friend_remark" UpdateFriends = "/friend/update_friends" + GetFriendHash = "/friend/friend_hash" AddBlackRouter = "/friend/add_black" RemoveBlackRouter = "/friend/remove_black" @@ -103,6 +104,7 @@ const ( SetGroupMemberNicknameRouter = RouterGroup + "/set_group_member_nickname" SetGroupMemberInfoRouter = RouterGroup + "/set_group_member_info" GetGroupAbstractInfoRouter = RouterGroup + "/get_group_abstract_info" + SearchGroupMember = RouterGroup + "/search_group_member" SetReceiveMessageOptRouter = "/conversation/set_receive_message_opt" GetReceiveMessageOptRouter = "/conversation/get_receive_message_opt" diff --git a/pkg/db/chat_log_model_v3.go b/pkg/db/chat_log_model_v3.go index d3d82ef6c..043cc6c05 100644 --- a/pkg/db/chat_log_model_v3.go +++ b/pkg/db/chat_log_model_v3.go @@ -26,7 +26,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) func (d *DataBase) initChatLog(ctx context.Context, conversationID string) { diff --git a/pkg/db/conversation_model.go b/pkg/db/conversation_model.go index 7c5e6c427..1fcba2dc5 100644 --- a/pkg/db/conversation_model.go +++ b/pkg/db/conversation_model.go @@ -25,8 +25,8 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" "gorm.io/gorm" ) diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index 76774dbf9..bad5d67a2 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -28,7 +28,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" diff --git a/pkg/db/upload_model.go b/pkg/db/upload_model.go index 9b3cd36ee..986c12836 100644 --- a/pkg/db/upload_model.go +++ b/pkg/db/upload_model.go @@ -22,7 +22,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "time" - "github.com/OpenIMSDK/tools/errs" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetUpload(ctx context.Context, partHash string) (*model_struct.LocalUpload, error) { diff --git a/pkg/sdk_params_callback/friend_sdk_struct.go b/pkg/sdk_params_callback/friend_sdk_struct.go index 6cee3f015..e58e0b24f 100644 --- a/pkg/sdk_params_callback/friend_sdk_struct.go +++ b/pkg/sdk_params_callback/friend_sdk_struct.go @@ -15,10 +15,10 @@ package sdk_params_callback import ( - "github.com/OpenIMSDK/protocol/wrapperspb" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" + "github.com/openimsdk/protocol/wrapperspb" ) // 1 diff --git a/pkg/sdk_params_callback/group_sdk_struct.go b/pkg/sdk_params_callback/group_sdk_struct.go index 3b5877ccd..200e296b1 100644 --- a/pkg/sdk_params_callback/group_sdk_struct.go +++ b/pkg/sdk_params_callback/group_sdk_struct.go @@ -60,9 +60,11 @@ type SearchGroupMembersParam struct { IsSearchUserID bool `json:"isSearchUserID"` IsSearchMemberNickname bool `json:"isSearchMemberNickname"` //offset, count int - Offset int `json:"offset"` - Count int `json:"count"` + Offset int `json:"offset"` + Count int `json:"count"` + PageNumber int `json:"pageNumber"` } + type SearchGroupMembersCallback []*model_struct.LocalGroupMember type SetGroupInfoParam struct { diff --git a/pkg/sdkerrs/error.go b/pkg/sdkerrs/error.go index 56e31b354..0470a72b9 100644 --- a/pkg/sdkerrs/error.go +++ b/pkg/sdkerrs/error.go @@ -14,10 +14,13 @@ package sdkerrs -import "github.com/OpenIMSDK/tools/errs" +import "github.com/openimsdk/tools/errs" func New(code int, msg string, dtl string) errs.CodeError { return errs.NewCodeError(code, msg).WithDetail(dtl) } -var Warp = errs.Wrap +var ( + Wrap = errs.Wrap + WrapMsg = errs.WrapMsg +) diff --git a/pkg/sdkerrs/predefine.go b/pkg/sdkerrs/predefine.go index bf0af003f..076d1fbdc 100644 --- a/pkg/sdkerrs/predefine.go +++ b/pkg/sdkerrs/predefine.go @@ -14,7 +14,7 @@ package sdkerrs -import "github.com/OpenIMSDK/tools/errs" +import "github.com/openimsdk/tools/errs" var ( ErrArgs = errs.NewCodeError(ArgsError, "ArgsError") diff --git a/pkg/server_api_params/auth_api_struct.go b/pkg/server_api_params/auth_api_struct.go index 44ea50de6..9868e3e0a 100644 --- a/pkg/server_api_params/auth_api_struct.go +++ b/pkg/server_api_params/auth_api_struct.go @@ -14,7 +14,7 @@ package server_api_params -import "github.com/OpenIMSDK/protocol/sdkws" +import "github.com/openimsdk/protocol/sdkws" //UserID string `protobuf:"bytes,1,opt,name=UserID" json:"UserID,omitempty"` // Nickname string `protobuf:"bytes,2,opt,name=Nickname" json:"Nickname,omitempty"` diff --git a/pkg/server_api_params/friend_api_struct.go b/pkg/server_api_params/friend_api_struct.go index d26bb0b93..7bfa3b871 100644 --- a/pkg/server_api_params/friend_api_struct.go +++ b/pkg/server_api_params/friend_api_struct.go @@ -14,7 +14,7 @@ package server_api_params -import "github.com/OpenIMSDK/protocol/sdkws" +import "github.com/openimsdk/protocol/sdkws" type ParamsCommFriend struct { OperationID string `json:"operationID" binding:"required"` diff --git a/pkg/server_api_params/group_api_struct.go b/pkg/server_api_params/group_api_struct.go index 381357ca6..4ff561227 100644 --- a/pkg/server_api_params/group_api_struct.go +++ b/pkg/server_api_params/group_api_struct.go @@ -14,7 +14,7 @@ package server_api_params -import "github.com/OpenIMSDK/protocol/sdkws" +import "github.com/openimsdk/protocol/sdkws" type CommResp struct { ErrCode int32 `json:"errCode"` diff --git a/pkg/server_api_params/user_api_struct.go b/pkg/server_api_params/user_api_struct.go index a4109b6b6..4db647f0e 100644 --- a/pkg/server_api_params/user_api_struct.go +++ b/pkg/server_api_params/user_api_struct.go @@ -15,7 +15,7 @@ package server_api_params import ( - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) type GetUsersInfoReq struct { diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index e4be19f01..38aeab161 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -20,7 +20,7 @@ import ( "github.com/google/go-cmp/cmp" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) // New creates a new Syncer instance with the provided synchronization functions. diff --git a/scripts/template/head.md.tmpl b/scripts/template/head.md.tmpl index c759ef5c5..dd4f12c85 100644 --- a/scripts/template/head.md.tmpl +++ b/scripts/template/head.md.tmpl @@ -4,9 +4,9 @@ We are excited to release {{.Tag}}, Branch: https://github.com/{{ .Env.USERNAME Learn more about versions of OpenIM: -+ For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) ++ For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/openimsdk/Open-IM-Server/blob/main/docs/conversions/version.md) -+ If you wish to use mirroring, read OpenIM's [🤲image management policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md) ++ If you wish to use mirroring, read OpenIM's [🤲image management policy](https://github.com/openimsdk/Open-IM-Server/blob/main/docs/conversions/images.md) **Want to be one of them 😘?** diff --git a/sdk_struct/sdk_struct.go b/sdk_struct/sdk_struct.go index 20a246afe..3698854d7 100644 --- a/sdk_struct/sdk_struct.go +++ b/sdk_struct/sdk_struct.go @@ -15,7 +15,7 @@ package sdk_struct import ( - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) ////////////////////////// message///////////////////////// diff --git a/test/account.go b/test/account.go index e3456a53b..99b9ae0f3 100644 --- a/test/account.go +++ b/test/account.go @@ -28,10 +28,10 @@ import ( "sync" "time" - authPB "github.com/OpenIMSDK/protocol/auth" - "github.com/OpenIMSDK/protocol/sdkws" - userPB "github.com/OpenIMSDK/protocol/user" - "github.com/OpenIMSDK/tools/log" + authPB "github.com/openimsdk/protocol/auth" + "github.com/openimsdk/protocol/sdkws" + userPB "github.com/openimsdk/protocol/user" + "github.com/openimsdk/tools/log" ) func GenUid(uid int, prefix string) string { diff --git a/test/login.go b/test/login.go index 46bf8b608..e457db619 100644 --- a/test/login.go +++ b/test/login.go @@ -18,11 +18,11 @@ import ( "encoding/json" "errors" "fmt" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/log" "time" ) diff --git a/test/reliability.go b/test/reliability.go index 2f05caa8b..5ddb760bf 100644 --- a/test/reliability.go +++ b/test/reliability.go @@ -17,8 +17,8 @@ package test import ( "errors" "fmt" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/log" "io/ioutil" "math/rand" "os" diff --git a/test/sendMessage.go b/test/sendMessage.go index 198a0c491..7472c7305 100644 --- a/test/sendMessage.go +++ b/test/sendMessage.go @@ -15,11 +15,11 @@ package test import ( - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" ) func init() { diff --git a/test/t_conversation_msg.go b/test/t_conversation_msg.go index 0a555076b..57e877070 100644 --- a/test/t_conversation_msg.go +++ b/test/t_conversation_msg.go @@ -17,18 +17,18 @@ package test import ( "encoding/json" "fmt" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/log" "sync" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" - "github.com/OpenIMSDK/tools/mcontext" + "github.com/openimsdk/tools/mcontext" ) //funcation DotestSetConversationRecvMessageOpt() { diff --git a/test/t_friend_sdk.go b/test/t_friend_sdk.go index 14aeb2054..6a3859579 100644 --- a/test/t_friend_sdk.go +++ b/test/t_friend_sdk.go @@ -18,20 +18,20 @@ import ( "encoding/json" "errors" "fmt" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/log" X "log" "os" "runtime" "time" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" - "github.com/OpenIMSDK/tools/mcontext" + "github.com/openimsdk/tools/mcontext" ) var loggerf *X.Logger diff --git a/test/t_group_sdk.go b/test/t_group_sdk.go index 294e39db6..e0d040661 100644 --- a/test/t_group_sdk.go +++ b/test/t_group_sdk.go @@ -22,8 +22,8 @@ import ( // "encoding/json" "fmt" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/log" //"open_im_sdk/internal/open_im_sdk" //"open_im_sdk/pkg/utils" // "open_im_sdk/internal/common" diff --git a/test/t_signaling.go b/test/t_signaling.go index b8c99dc95..052bf1ddf 100644 --- a/test/t_signaling.go +++ b/test/t_signaling.go @@ -17,7 +17,7 @@ package test import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" "golang.org/x/net/context" ) diff --git a/test/work_group_create.go b/test/work_group_create.go index 2807fef8d..4bcca7958 100644 --- a/test/work_group_create.go +++ b/test/work_group_create.go @@ -17,15 +17,15 @@ package test import ( "encoding/json" "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/network" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/log" "sync" "time" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) var ( diff --git a/testv2/config.go b/testv2/config.go index 94f24a22e..1822cb3ff 100644 --- a/testv2/config.go +++ b/testv2/config.go @@ -15,8 +15,8 @@ package testv2 import ( - "github.com/OpenIMSDK/protocol/constant" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/protocol/constant" ) const ( diff --git a/testv2/empty_test.go b/testv2/empty_test.go index 3824f62d7..fa94f1ae9 100644 --- a/testv2/empty_test.go +++ b/testv2/empty_test.go @@ -15,8 +15,8 @@ package testv2 import ( - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" + "github.com/openimsdk/tools/log" "testing" "time" ) diff --git a/testv2/friend_test.go b/testv2/friend_test.go index 56b8f2084..0e794f84e 100644 --- a/testv2/friend_test.go +++ b/testv2/friend_test.go @@ -15,13 +15,13 @@ package testv2 import ( - "github.com/OpenIMSDK/protocol/wrapperspb" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" + "github.com/openimsdk/protocol/wrapperspb" "testing" "time" - friend2 "github.com/OpenIMSDK/protocol/friend" + friend2 "github.com/openimsdk/protocol/friend" ) func Test_GetSpecifiedFriendsInfo(t *testing.T) { diff --git a/testv2/group_test.go b/testv2/group_test.go index 84c4ab300..73061fd9c 100644 --- a/testv2/group_test.go +++ b/testv2/group_test.go @@ -15,12 +15,12 @@ package testv2 import ( - "github.com/OpenIMSDK/protocol/group" - "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/protocol/wrapperspb" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/protocol/wrapperspb" "testing" ) diff --git a/testv2/init.go b/testv2/init.go index 9cc0afe4a..354cb7393 100644 --- a/testv2/init.go +++ b/testv2/init.go @@ -19,16 +19,16 @@ import ( "context" "encoding/json" "fmt" - "github.com/OpenIMSDK/protocol/constant" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" + "github.com/openimsdk/protocol/constant" "io" "math/rand" "net/http" "strconv" "time" - "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/tools/log" ) var ( diff --git a/testv2/listener.go b/testv2/listener.go index 52eb3a4bf..085552304 100644 --- a/testv2/listener.go +++ b/testv2/listener.go @@ -16,6 +16,8 @@ package testv2 type OnConnListener struct{} +func (c *OnConnListener) OnUserTokenInvalid(errMsg string) {} + func (c *OnConnListener) OnConnecting() { // fmt.Println("OnConnecting") } diff --git a/testv2/user_test.go b/testv2/user_test.go index b77139911..229928f76 100644 --- a/testv2/user_test.go +++ b/testv2/user_test.go @@ -16,14 +16,14 @@ package testv2 import ( "fmt" - "github.com/OpenIMSDK/protocol/user" - "github.com/OpenIMSDK/protocol/wrapperspb" + "github.com/openimsdk/protocol/user" + "github.com/openimsdk/protocol/wrapperspb" "testing" "time" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" - "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/protocol/sdkws" ) func Test_GetSelfUserInfo(t *testing.T) { diff --git a/wasm/event_listener/caller.go b/wasm/event_listener/caller.go index 992370353..efe71ea50 100644 --- a/wasm/event_listener/caller.go +++ b/wasm/event_listener/caller.go @@ -21,9 +21,9 @@ import ( "bytes" "context" "errors" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/wasm/exec" + "github.com/openimsdk/tools/log" "reflect" "strconv" "strings" diff --git a/wasm/exec/executor.go b/wasm/exec/executor.go index 983efd580..82d1d2d89 100644 --- a/wasm/exec/executor.go +++ b/wasm/exec/executor.go @@ -20,9 +20,9 @@ package exec import ( "context" "errors" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" "runtime" "syscall/js" "time" From aec49f0b37c6ea09fc72e9a683cacc668505b954 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 28 May 2024 19:02:45 +0800 Subject: [PATCH 02/69] group hash --- go.mod | 4 + internal/friend/conversion.go | 26 +++++ internal/friend/sync.go | 51 ++++----- internal/friend/sync2.go | 139 +++++++++++++++++++++++ pkg/constant/server_api_router.go | 2 +- pkg/db/db_interface/databse.go | 6 + pkg/db/model_struct/data_model_struct.go | 14 +++ 7 files changed, 215 insertions(+), 27 deletions(-) create mode 100644 internal/friend/sync2.go diff --git a/go.mod b/go.mod index 2f25f6d3e..a157038ef 100644 --- a/go.mod +++ b/go.mod @@ -41,3 +41,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/grpc v1.62.1 // indirect ) + +replace ( + github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol +) diff --git a/internal/friend/conversion.go b/internal/friend/conversion.go index 0917f76cd..4e5369fea 100644 --- a/internal/friend/conversion.go +++ b/internal/friend/conversion.go @@ -16,6 +16,7 @@ package friend import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/protocol/friend" "github.com/openimsdk/protocol/sdkws" ) @@ -70,3 +71,28 @@ func ServerBlackToLocalBlack(info *sdkws.BlackInfo) *model_struct.LocalBlack { //AttachedInfo: info.FriendUser.AttachedInfo, } } + +func ServerFriendToLocalFriendV2(info *friend.FriendInfo) *model_struct.LocalFriend { + return &model_struct.LocalFriend{ + OwnerUserID: info.OwnerUserID, + FriendUserID: info.FriendUserID, + Remark: info.Remark, + CreateTime: info.CreateTime, + AddSource: info.AddSource, + OperatorUserID: info.OperatorUserID, + Nickname: info.FriendNickname, + FaceURL: info.FriendFaceURL, + Ex: info.Ex, + //AttachedInfo: info.FriendUser.AttachedInfo, + IsPinned: info.IsPinned, + } +} + +func BatchServerFriendToLocalFriend(infos []*friend.FriendInfo) []*model_struct.LocalFriend { + res := make([]*model_struct.LocalFriend, 0, len(infos)) + for i, info := range infos { + elem := ServerFriendToLocalFriendV2(info) + elem.SortValue = int32(i) + } + return res +} diff --git a/internal/friend/sync.go b/internal/friend/sync.go index 31bf27007..3ac4aa9f7 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -19,7 +19,6 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" - pconstant "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/friend" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" @@ -117,31 +116,31 @@ func (f *Friend) SyncFriends(ctx context.Context, friendIDs []string) error { return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo), localData, nil) } -func (f *Friend) SyncFriendPart(ctx context.Context) error { - hashResp, err := util.CallApi[friend.GetFriendHashResp](ctx, constant.GetFriendHash, &friend.GetFriendHashReq{UserID: f.loginUserID}) - if err != nil { - return err - } - friends, err := f.db.GetAllFriendList(ctx) - if err != nil { - return err - } - hashCode := f.CalculateHash(friends) - log.ZDebug(ctx, "SyncFriendPart", "serverHash", hashResp.Hash, "serverTotal", hashResp.Total, "localHash", hashCode, "localTotal", len(friends)) - if hashCode == hashResp.Hash { - return nil - } - req := &friend.GetPaginationFriendsReq{ - UserID: f.loginUserID, - Pagination: &sdkws.RequestPagination{PageNumber: pconstant.FirstPageNumber, ShowNumber: pconstant.MaxSyncPullNumber}, - } - resp, err := util.CallApi[friend.GetPaginationFriendsResp](ctx, constant.GetFriendListRouter, req) - if err != nil { - return err - } - serverFriends := util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo) - return f.friendSyncer.Sync(ctx, serverFriends, friends, nil) -} +//func (f *Friend) SyncFriendPart(ctx context.Context) error { +// hashResp, err := util.CallApi[friend.GetFriendHashResp](ctx, constant.GetFriendHash, &friend.GetFriendHashReq{UserID: f.loginUserID}) +// if err != nil { +// return err +// } +// friends, err := f.db.GetAllFriendList(ctx) +// if err != nil { +// return err +// } +// hashCode := f.CalculateHash(friends) +// log.ZDebug(ctx, "SyncFriendPart", "serverHash", hashResp.Hash, "serverTotal", hashResp.Total, "localHash", hashCode, "localTotal", len(friends)) +// if hashCode == hashResp.Hash { +// return nil +// } +// req := &friend.GetPaginationFriendsReq{ +// UserID: f.loginUserID, +// Pagination: &sdkws.RequestPagination{PageNumber: pconstant.FirstPageNumber, ShowNumber: pconstant.MaxSyncPullNumber}, +// } +// resp, err := util.CallApi[friend.GetPaginationFriendsResp](ctx, constant.GetFriendListRouter, req) +// if err != nil { +// return err +// } +// serverFriends := util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo) +// return f.friendSyncer.Sync(ctx, serverFriends, friends, nil) +//} func (f *Friend) SyncAllBlackList(ctx context.Context) error { req := &friend.GetPaginationBlacksReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go new file mode 100644 index 000000000..dbf44028b --- /dev/null +++ b/internal/friend/sync2.go @@ -0,0 +1,139 @@ +package friend + +import ( + "context" + "crypto/md5" + "encoding/binary" + "encoding/json" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/protocol/friend" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" + "time" +) + +func (f *Friend) getVersionFriendKey() string { + return "friend:" + f.loginUserID +} + +func (f *Friend) IncrSyncFriends(ctx context.Context) error { + local, err := f.db.GetAllFriendList(ctx) + if err != nil { + return err + } + userIDs := datautil.Slice(local, func(v *model_struct.LocalFriend) string { + return v.FriendUserID + }) + req := &friend.GetIncrementalFriendsReq{ + UserID: f.loginUserID, + IdHash: IDHash(userIDs), + } + key := f.getVersionFriendKey() + if res, err := f.db.GetVersionSync(ctx, key); err == nil { + req.VersionID = res.VersionID + req.Version = res.Version + req.IdHash = res.IDHash + } else { + log.ZWarn(ctx, "get version sync failed", err, "key", key) + } + resp, err := util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, req) + if err != nil { + return err + } + if len(resp.DeleteUserIds)+len(resp.Changes)+len(resp.SortUserIds) == 0 { + return nil + } + if NotChange(resp.DeleteUserIds, resp.SortUserIds, resp.Changes) { + return nil + } + b := Builder[string, *model_struct.LocalFriend]{ + Local: local, + Key: func(v *model_struct.LocalFriend) string { + return v.FriendUserID + }, + Sort: func(v *model_struct.LocalFriend, index int32) *model_struct.LocalFriend { + v.SortValue = index + return v + }, + Full: resp.Full, + SortKeys: resp.SortUserIds, + DeleteKeys: resp.DeleteUserIds, + Changes: util.Batch(ServerFriendToLocalFriendV2, resp.Changes), + } + if err := f.friendSyncer.Sync(ctx, b.Build(), local, nil); err != nil { + return err + } + lv := model_struct.LocalVersionSync{ + Key: key, + VersionID: resp.VersionID, + Version: resp.Version, + IDHash: 0, + CreateTime: time.Now().UnixMilli(), + } + if err := f.db.SetVersionSync(ctx, &lv); err != nil { + return err + } + return nil +} + +type Builder[K comparable, V any] struct { + Local []V + Key func(V) K + Sort func(v V, index int32) V + Full bool + SortKeys []K + DeleteKeys []K + Changes []V +} + +func (b *Builder[K, V]) Build() []V { + if b.Full { + for i := range b.Changes { + b.Changes[i] = b.Sort(b.Changes[i], int32(i)) + } + return b.Changes + } + tmp := make(map[K]V) + for i, e := range b.Local { + tmp[b.Key(e)] = b.Local[i] + } + for _, key := range b.DeleteKeys { + delete(tmp, key) + } + for i, e := range b.Changes { + tmp[b.Key(e)] = b.Changes[i] + } + res := make([]V, 0, len(tmp)) + var incr int32 + if len(b.SortKeys) > 0 { + for _, key := range b.SortKeys { + if v, ok := tmp[key]; ok { + incr++ + res = append(res, b.Sort(v, incr)) + } + } + } else { + for _, t := range b.Local { + if v, ok := tmp[b.Key(t)]; ok { + incr++ + res = append(res, b.Sort(v, incr)) + } + } + } + return res +} + +func NotChange[K comparable, V any](delKeys []K, sortKeys []K, changes []V) bool { + return len(delKeys)+len(sortKeys)+len(changes) > 0 +} + +func IDHash(ids []string) uint64 { + if len(ids) == 0 { + return 0 + } + data, _ := json.Marshal(ids) + sum := md5.Sum(data) + return binary.BigEndian.Uint64(sum[:]) +} diff --git a/pkg/constant/server_api_router.go b/pkg/constant/server_api_router.go index 269d7dd8c..8d20e99c5 100644 --- a/pkg/constant/server_api_router.go +++ b/pkg/constant/server_api_router.go @@ -45,7 +45,7 @@ const ( AddFriendResponse = "/friend/add_friend_response" SetFriendRemark = "/friend/set_friend_remark" UpdateFriends = "/friend/update_friends" - GetFriendHash = "/friend/friend_hash" + GetIncrementalFriends = "/friend/get_incremental_friends" AddBlackRouter = "/friend/add_black" RemoveBlackRouter = "/friend/remove_black" diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index 8f0121599..a497b9934 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -273,6 +273,11 @@ type SendingMessagesModel interface { GetAllSendingMessages(ctx context.Context) (friendRequests []*model_struct.LocalSendingMessages, err error) } +type VersionSyncModel interface { + GetVersionSync(ctx context.Context, key string) (*model_struct.LocalVersionSync, error) + SetVersionSync(ctx context.Context, version *model_struct.LocalVersionSync) error +} + type DataBase interface { Close(ctx context.Context) error InitDB(ctx context.Context, userID string, dataDir string) error @@ -284,4 +289,5 @@ type DataBase interface { ReactionModel S3Model SendingMessagesModel + VersionSyncModel } diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index b6aa075a6..825434e02 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -58,6 +58,7 @@ type LocalFriend struct { Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` IsPinned bool `gorm:"column:is_pinned;" json:"isPinned"` + SortValue int32 `gorm:"column:sort_value" json:"sortValue"` } // message FriendRequest{ @@ -535,3 +536,16 @@ type LocalUserCommand struct { func (LocalUserCommand) TableName() string { return "local_user_command" } + +type LocalVersionSync struct { + Key string `gorm:"column:key;type:varchar(255);primary_key" json:"key"` + VersionID string `gorm:"column:version_id" json:"versionID"` + Version uint64 `gorm:"column:version" json:"version"` + IDHash uint64 `gorm:"column:id_hash" json:"idHash"` + Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` + CreateTime int64 `gorm:"column:create_time" json:"createTime"` +} + +func (LocalVersionSync) TableName() string { + return "local_sync_version" +} From 0c4aa61ef996a153da470e1f217bf614d96ddfd9 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Fri, 31 May 2024 18:40:36 +0800 Subject: [PATCH 03/69] sync --- internal/friend/conversion.go | 9 --- internal/friend/sync2.go | 84 ++++++------------------ pkg/db/db_init.go | 2 + pkg/db/model_struct/data_model_struct.go | 13 +--- pkg/db/version_sync.go | 32 +++++++++ testv2/config.go | 6 +- testv2/sync2_test.go | 30 +++++++++ 7 files changed, 91 insertions(+), 85 deletions(-) create mode 100644 pkg/db/version_sync.go create mode 100644 testv2/sync2_test.go diff --git a/internal/friend/conversion.go b/internal/friend/conversion.go index 4e5369fea..ec16aae18 100644 --- a/internal/friend/conversion.go +++ b/internal/friend/conversion.go @@ -87,12 +87,3 @@ func ServerFriendToLocalFriendV2(info *friend.FriendInfo) *model_struct.LocalFri IsPinned: info.IsPinned, } } - -func BatchServerFriendToLocalFriend(infos []*friend.FriendInfo) []*model_struct.LocalFriend { - res := make([]*model_struct.LocalFriend, 0, len(infos)) - for i, info := range infos { - elem := ServerFriendToLocalFriendV2(info) - elem.SortValue = int32(i) - } - return res -} diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index dbf44028b..28137a969 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -2,9 +2,6 @@ package friend import ( "context" - "crypto/md5" - "encoding/binary" - "encoding/json" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" @@ -19,22 +16,13 @@ func (f *Friend) getVersionFriendKey() string { } func (f *Friend) IncrSyncFriends(ctx context.Context) error { - local, err := f.db.GetAllFriendList(ctx) - if err != nil { - return err - } - userIDs := datautil.Slice(local, func(v *model_struct.LocalFriend) string { - return v.FriendUserID - }) req := &friend.GetIncrementalFriendsReq{ UserID: f.loginUserID, - IdHash: IDHash(userIDs), } key := f.getVersionFriendKey() if res, err := f.db.GetVersionSync(ctx, key); err == nil { req.VersionID = res.VersionID req.Version = res.Version - req.IdHash = res.IDHash } else { log.ZWarn(ctx, "get version sync failed", err, "key", key) } @@ -42,23 +30,25 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { if err != nil { return err } - if len(resp.DeleteUserIds)+len(resp.Changes)+len(resp.SortUserIds) == 0 { - return nil + if NotChange(resp.DeleteUserIds, resp.Changes) { + lv := model_struct.LocalVersionSync{ + Key: key, + VersionID: resp.VersionID, + Version: resp.Version, + CreateTime: time.Now().UnixMilli(), + } + return f.db.SetVersionSync(ctx, &lv) } - if NotChange(resp.DeleteUserIds, resp.SortUserIds, resp.Changes) { - return nil + local, err := f.db.GetAllFriendList(ctx) + if err != nil { + return err } b := Builder[string, *model_struct.LocalFriend]{ Local: local, Key: func(v *model_struct.LocalFriend) string { return v.FriendUserID }, - Sort: func(v *model_struct.LocalFriend, index int32) *model_struct.LocalFriend { - v.SortValue = index - return v - }, Full: resp.Full, - SortKeys: resp.SortUserIds, DeleteKeys: resp.DeleteUserIds, Changes: util.Batch(ServerFriendToLocalFriendV2, resp.Changes), } @@ -69,7 +59,6 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { Key: key, VersionID: resp.VersionID, Version: resp.Version, - IDHash: 0, CreateTime: time.Now().UnixMilli(), } if err := f.db.SetVersionSync(ctx, &lv); err != nil { @@ -81,59 +70,28 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { type Builder[K comparable, V any] struct { Local []V Key func(V) K - Sort func(v V, index int32) V Full bool - SortKeys []K DeleteKeys []K Changes []V } func (b *Builder[K, V]) Build() []V { if b.Full { - for i := range b.Changes { - b.Changes[i] = b.Sort(b.Changes[i], int32(i)) - } return b.Changes } - tmp := make(map[K]V) - for i, e := range b.Local { - tmp[b.Key(e)] = b.Local[i] - } - for _, key := range b.DeleteKeys { - delete(tmp, key) + res := make([]V, 0, len(b.Local)+len(b.Changes)) + var delSet map[K]struct{} + if len(b.Local)+len(b.DeleteKeys) > 0 { + delSet = datautil.SliceSet(b.DeleteKeys) } - for i, e := range b.Changes { - tmp[b.Key(e)] = b.Changes[i] - } - res := make([]V, 0, len(tmp)) - var incr int32 - if len(b.SortKeys) > 0 { - for _, key := range b.SortKeys { - if v, ok := tmp[key]; ok { - incr++ - res = append(res, b.Sort(v, incr)) - } - } - } else { - for _, t := range b.Local { - if v, ok := tmp[b.Key(t)]; ok { - incr++ - res = append(res, b.Sort(v, incr)) - } + for i, v := range b.Local { + if _, ok := delSet[b.Key(v)]; !ok { + res = append(res, b.Local[i]) } } - return res -} - -func NotChange[K comparable, V any](delKeys []K, sortKeys []K, changes []V) bool { - return len(delKeys)+len(sortKeys)+len(changes) > 0 + return append(res, b.Changes...) } -func IDHash(ids []string) uint64 { - if len(ids) == 0 { - return 0 - } - data, _ := json.Marshal(ids) - sum := md5.Sum(data) - return binary.BigEndian.Uint64(sum[:]) +func NotChange[K comparable, V any](delKeys []K, changes []V) bool { + return len(delKeys)+len(changes) == 0 } diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index bad5d67a2..e5cba7309 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -42,6 +42,7 @@ type DataBase struct { groupMtx sync.RWMutex friendMtx sync.RWMutex userMtx sync.RWMutex + versionMtx sync.RWMutex superGroupMtx sync.RWMutex } @@ -148,6 +149,7 @@ func (d *DataBase) initDB(ctx context.Context, logLevel int) error { &model_struct.LocalStranger{}, &model_struct.LocalSendingMessages{}, &model_struct.LocalUserCommand{}, + &model_struct.LocalVersionSync{}, ) if err != nil { return err diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 825434e02..7e59839e9 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -51,14 +51,9 @@ type LocalFriend struct { OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"` Nickname string `gorm:"column:name;type:varchar;type:varchar(255)" json:"nickname"` FaceURL string `gorm:"column:face_url;type:varchar;type:varchar(255)" json:"faceURL"` - //Gender int32 `gorm:"column:gender" json:"gender"` - //PhoneNumber string `gorm:"column:phone_number;type:varchar(32)" json:"phoneNumber"` - //Birth uint32 `gorm:"column:birth" json:"birth"` - //Email string `gorm:"column:email;type:varchar(64)" json:"email"` - Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` - AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` - IsPinned bool `gorm:"column:is_pinned;" json:"isPinned"` - SortValue int32 `gorm:"column:sort_value" json:"sortValue"` + Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` + AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` + IsPinned bool `gorm:"column:is_pinned;" json:"isPinned"` } // message FriendRequest{ @@ -541,8 +536,6 @@ type LocalVersionSync struct { Key string `gorm:"column:key;type:varchar(255);primary_key" json:"key"` VersionID string `gorm:"column:version_id" json:"versionID"` Version uint64 `gorm:"column:version" json:"version"` - IDHash uint64 `gorm:"column:id_hash" json:"idHash"` - Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` CreateTime int64 `gorm:"column:create_time" json:"createTime"` } diff --git a/pkg/db/version_sync.go b/pkg/db/version_sync.go new file mode 100644 index 000000000..34cb19d9f --- /dev/null +++ b/pkg/db/version_sync.go @@ -0,0 +1,32 @@ +package db + +import ( + "context" + "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "gorm.io/gorm" +) + +func (d *DataBase) GetVersionSync(ctx context.Context, key string) (*model_struct.LocalVersionSync, error) { + d.versionMtx.RLock() + defer d.versionMtx.RUnlock() + var res model_struct.LocalVersionSync + return &res, utils.Wrap(d.conn.WithContext(ctx).Where("`key` = ? ", key).Take(&res).Error, "GetVersionSync failed") +} + +func (d *DataBase) SetVersionSync(ctx context.Context, lv *model_struct.LocalVersionSync) error { + d.versionMtx.Lock() + defer d.versionMtx.Unlock() + res := d.conn.WithContext(ctx).Where("`key` = ?", lv.Key).Save(lv) + if res.Error != nil { + return utils.Wrap(res.Error, "SetVersionSync failed") + } + if res.RowsAffected > 0 { + return nil + } + if err := d.conn.WithContext(ctx).Create(lv).Error; err != nil && !errors.Is(err, gorm.ErrDuplicatedKey) { + return utils.Wrap(err, "SetVersionSync failed") + } + return nil +} diff --git a/testv2/config.go b/testv2/config.go index 1822cb3ff..1f8c8582c 100644 --- a/testv2/config.go +++ b/testv2/config.go @@ -20,9 +20,9 @@ import ( ) const ( - APIADDR = "http://14.29.168.56:10002" - WSADDR = "ws://14.29.168.56:10001" - UserID = "3" + APIADDR = "http://172.16.8.48:10002" + WSADDR = "ws://172.16.8.48:10001" + UserID = "6864873394" friendUserID = "3281432310" ) diff --git a/testv2/sync2_test.go b/testv2/sync2_test.go new file mode 100644 index 000000000..83c40e9b5 --- /dev/null +++ b/testv2/sync2_test.go @@ -0,0 +1,30 @@ +// Copyright © 2023 OpenIM SDK. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package testv2 + +import ( + "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" + "testing" +) + +func TestSyncFriend2(t *testing.T) { + for i := 0; ; i++ { + if err := open_im_sdk.UserForSDK.Friend().IncrSyncFriends(ctx); err != nil { + t.Log("error-->", err) + //panic(err) + } + } + //select {} +} From f996470aaf8b1c6de9c6ec661c81eaf43014007e Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Sat, 1 Jun 2024 21:34:27 +0800 Subject: [PATCH 04/69] sync --- go.mod | 8 +- go.sum | 12 +-- internal/friend/sync2.go | 162 +++++++++++++++++++++++---------------- 3 files changed, 100 insertions(+), 82 deletions(-) diff --git a/go.mod b/go.mod index a157038ef..b68d1aa5c 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require golang.org/x/net v0.22.0 require ( github.com/google/go-cmp v0.6.0 - github.com/openimsdk/protocol v0.0.66 + github.com/openimsdk/protocol v0.0.69-alpha.3 github.com/openimsdk/tools v0.0.49-alpha.9 github.com/patrickmn/go-cache v2.1.0+incompatible go.etcd.io/etcd/api/v3 v3.5.13 @@ -42,6 +42,6 @@ require ( google.golang.org/grpc v1.62.1 // indirect ) -replace ( - github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol -) +//replace ( +// github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol +//) diff --git a/go.sum b/go.sum index 1af3a2f24..d79781630 100644 --- a/go.sum +++ b/go.sum @@ -15,7 +15,6 @@ github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= @@ -26,12 +25,10 @@ github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkL github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= -github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= -github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/openimsdk/protocol v0.0.66 h1:AVYufQ+A7pQpemjaOtr62dwVa6Z2o6lN4d8erPch8NE= -github.com/openimsdk/protocol v0.0.66/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= +github.com/openimsdk/protocol v0.0.69-alpha.3 h1:Uf167FVB5EqYpiy2zBbR63OiK+Njjy99fXYasK6Zi+4= +github.com/openimsdk/protocol v0.0.69-alpha.3/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= github.com/openimsdk/tools v0.0.49-alpha.9 h1:yoa3GS6t0d1mRv/S86niFBGDgSjy2EWWwBI5NAH1Kgk= github.com/openimsdk/tools v0.0.49-alpha.9/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= @@ -72,13 +69,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= -gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= -gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo= -gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index 28137a969..ef7892a88 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -4,6 +4,7 @@ import ( "context" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/protocol/friend" "github.com/openimsdk/tools/log" @@ -11,87 +12,112 @@ import ( "time" ) -func (f *Friend) getVersionFriendKey() string { - return "friend:" + f.loginUserID -} - func (f *Friend) IncrSyncFriends(ctx context.Context) error { - req := &friend.GetIncrementalFriendsReq{ - UserID: f.loginUserID, + opt := Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ + Ctx: ctx, + DB: f.db, + Key: func(localFriend *model_struct.LocalFriend) string { + return localFriend.FriendUserID + }, + SyncKey: func() string { + return "friend:" + f.loginUserID + }, + Local: func() ([]*model_struct.LocalFriend, error) { + return f.db.GetAllFriendList(ctx) + }, + Server: func(version *model_struct.LocalVersionSync) (*friend.GetIncrementalFriendsResp, error) { + return util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, &friend.GetIncrementalFriendsReq{ + UserID: f.loginUserID, + Version: version.Version, + VersionID: version.VersionID, + }) + }, + Full: func(resp *friend.GetIncrementalFriendsResp) bool { + return resp.Full + }, + Version: func(resp *friend.GetIncrementalFriendsResp) (string, uint64) { + return resp.VersionID, resp.Version + }, + DeleteIDs: func(resp *friend.GetIncrementalFriendsResp) []string { + return resp.DeleteUserIds + }, + Changes: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { + return util.Batch(ServerFriendToLocalFriendV2, resp.Changes) + }, + Syncer: func(server, local []*model_struct.LocalFriend) error { + return f.friendSyncer.Sync(ctx, server, local, nil) + }, } - key := f.getVersionFriendKey() - if res, err := f.db.GetVersionSync(ctx, key); err == nil { - req.VersionID = res.VersionID - req.Version = res.Version - } else { - log.ZWarn(ctx, "get version sync failed", err, "key", key) + return opt.Sync() +} + +type Option[V, R any] struct { + Ctx context.Context + DB db_interface.VersionSyncModel + Key func(V) string + SyncKey func() string + Local func() ([]V, error) + Server func(version *model_struct.LocalVersionSync) (R, error) + Full func(resp R) bool + Version func(resp R) (string, uint64) + DeleteIDs func(resp R) []string + Changes func(resp R) []V + Syncer func(server, local []V) error +} + +func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { + key := o.SyncKey() + versionInfo, err := o.DB.GetVersionSync(o.Ctx, key) + if err != nil { + log.ZInfo(o.Ctx, "get version info", "error", err) + return &model_struct.LocalVersionSync{ + Key: key, + } } - resp, err := util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, req) + return versionInfo +} + +func (o *Option[V, R]) Sync() error { + versionInfo := o.getVersionInfo() + resp, err := o.Server(versionInfo) if err != nil { return err } - if NotChange(resp.DeleteUserIds, resp.Changes) { - lv := model_struct.LocalVersionSync{ - Key: key, - VersionID: resp.VersionID, - Version: resp.Version, + delIDs := o.DeleteIDs(resp) + changes := o.Changes(resp) + updateVersionInfo := func() error { + lvs := &model_struct.LocalVersionSync{ + Key: versionInfo.Key, CreateTime: time.Now().UnixMilli(), } - return f.db.SetVersionSync(ctx, &lv) + lvs.VersionID, lvs.Version = o.Version(resp) + return o.DB.SetVersionSync(o.Ctx, lvs) } - local, err := f.db.GetAllFriendList(ctx) - if err != nil { - return err - } - b := Builder[string, *model_struct.LocalFriend]{ - Local: local, - Key: func(v *model_struct.LocalFriend) string { - return v.FriendUserID - }, - Full: resp.Full, - DeleteKeys: resp.DeleteUserIds, - Changes: util.Batch(ServerFriendToLocalFriendV2, resp.Changes), + if len(delIDs)+len(changes) == 0 { + return updateVersionInfo() } - if err := f.friendSyncer.Sync(ctx, b.Build(), local, nil); err != nil { + local, err := o.Local() + if err != nil { return err } - lv := model_struct.LocalVersionSync{ - Key: key, - VersionID: resp.VersionID, - Version: resp.Version, - CreateTime: time.Now().UnixMilli(), + var server []V + if o.Full(resp) { + server = changes + } else { + kv := datautil.SliceToMapAny(local, func(v V) (string, V) { + return o.Key(v), v + }) + for i, change := range changes { + key := o.Key(change) + kv[key] = changes[i] + } + for _, id := range delIDs { + delete(kv, id) + } + server = datautil.Values(kv) } - if err := f.db.SetVersionSync(ctx, &lv); err != nil { + if err := o.Syncer(server, local); err != nil { return err } - return nil -} - -type Builder[K comparable, V any] struct { - Local []V - Key func(V) K - Full bool - DeleteKeys []K - Changes []V -} - -func (b *Builder[K, V]) Build() []V { - if b.Full { - return b.Changes - } - res := make([]V, 0, len(b.Local)+len(b.Changes)) - var delSet map[K]struct{} - if len(b.Local)+len(b.DeleteKeys) > 0 { - delSet = datautil.SliceSet(b.DeleteKeys) - } - for i, v := range b.Local { - if _, ok := delSet[b.Key(v)]; !ok { - res = append(res, b.Local[i]) - } - } - return append(res, b.Changes...) -} - -func NotChange[K comparable, V any](delKeys []K, changes []V) bool { - return len(delKeys)+len(changes) == 0 + return updateVersionInfo() } From 9d131c8ccd2d7cd77ce6ffccd7ce70105769176a Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 3 Jun 2024 10:19:02 +0800 Subject: [PATCH 05/69] sync --- internal/friend/sync2.go | 78 +------------------------------- internal/incrversion/option.go | 81 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 76 deletions(-) create mode 100644 internal/incrversion/option.go diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index ef7892a88..04070a01c 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -2,18 +2,15 @@ package friend import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" - "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/protocol/friend" - "github.com/openimsdk/tools/log" - "github.com/openimsdk/tools/utils/datautil" - "time" ) func (f *Friend) IncrSyncFriends(ctx context.Context) error { - opt := Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ + opt := incrversion.Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ Ctx: ctx, DB: f.db, Key: func(localFriend *model_struct.LocalFriend) string { @@ -50,74 +47,3 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { } return opt.Sync() } - -type Option[V, R any] struct { - Ctx context.Context - DB db_interface.VersionSyncModel - Key func(V) string - SyncKey func() string - Local func() ([]V, error) - Server func(version *model_struct.LocalVersionSync) (R, error) - Full func(resp R) bool - Version func(resp R) (string, uint64) - DeleteIDs func(resp R) []string - Changes func(resp R) []V - Syncer func(server, local []V) error -} - -func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { - key := o.SyncKey() - versionInfo, err := o.DB.GetVersionSync(o.Ctx, key) - if err != nil { - log.ZInfo(o.Ctx, "get version info", "error", err) - return &model_struct.LocalVersionSync{ - Key: key, - } - } - return versionInfo -} - -func (o *Option[V, R]) Sync() error { - versionInfo := o.getVersionInfo() - resp, err := o.Server(versionInfo) - if err != nil { - return err - } - delIDs := o.DeleteIDs(resp) - changes := o.Changes(resp) - updateVersionInfo := func() error { - lvs := &model_struct.LocalVersionSync{ - Key: versionInfo.Key, - CreateTime: time.Now().UnixMilli(), - } - lvs.VersionID, lvs.Version = o.Version(resp) - return o.DB.SetVersionSync(o.Ctx, lvs) - } - if len(delIDs)+len(changes) == 0 { - return updateVersionInfo() - } - local, err := o.Local() - if err != nil { - return err - } - var server []V - if o.Full(resp) { - server = changes - } else { - kv := datautil.SliceToMapAny(local, func(v V) (string, V) { - return o.Key(v), v - }) - for i, change := range changes { - key := o.Key(change) - kv[key] = changes[i] - } - for _, id := range delIDs { - delete(kv, id) - } - server = datautil.Values(kv) - } - if err := o.Syncer(server, local); err != nil { - return err - } - return updateVersionInfo() -} diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go new file mode 100644 index 000000000..f54ab7168 --- /dev/null +++ b/internal/incrversion/option.go @@ -0,0 +1,81 @@ +package incrversion + +import ( + "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" + "time" +) + +type Option[V, R any] struct { + Ctx context.Context + DB db_interface.VersionSyncModel + Key func(V) string + SyncKey func() string + Local func() ([]V, error) + Server func(version *model_struct.LocalVersionSync) (R, error) + Full func(resp R) bool + Version func(resp R) (string, uint64) + DeleteIDs func(resp R) []string + Changes func(resp R) []V + Syncer func(server, local []V) error +} + +func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { + key := o.SyncKey() + versionInfo, err := o.DB.GetVersionSync(o.Ctx, key) + if err != nil { + log.ZInfo(o.Ctx, "get version info", "error", err) + return &model_struct.LocalVersionSync{ + Key: key, + } + } + return versionInfo +} + +func (o *Option[V, R]) Sync() error { + versionInfo := o.getVersionInfo() + resp, err := o.Server(versionInfo) + if err != nil { + return err + } + delIDs := o.DeleteIDs(resp) + changes := o.Changes(resp) + updateVersionInfo := func() error { + lvs := &model_struct.LocalVersionSync{ + Key: versionInfo.Key, + CreateTime: time.Now().UnixMilli(), + } + lvs.VersionID, lvs.Version = o.Version(resp) + return o.DB.SetVersionSync(o.Ctx, lvs) + } + if len(delIDs)+len(changes) == 0 { + return updateVersionInfo() + } + local, err := o.Local() + if err != nil { + return err + } + var server []V + if o.Full(resp) { + server = changes + } else { + kv := datautil.SliceToMapAny(local, func(v V) (string, V) { + return o.Key(v), v + }) + for i, change := range changes { + key := o.Key(change) + kv[key] = changes[i] + } + for _, id := range delIDs { + delete(kv, id) + } + server = datautil.Values(kv) + } + if err := o.Syncer(server, local); err != nil { + return err + } + return updateVersionInfo() +} From 9c821d598e90a021e6bc2c1521f2f0ce3eb188e7 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 3 Jun 2024 18:43:21 +0800 Subject: [PATCH 06/69] group sync --- internal/group/sdk.go | 37 ++++--- internal/group/sync.go | 1 + internal/group/sync2.go | 164 ++++++++++++++++++++++++++++++ internal/incrversion/option.go | 39 ++++--- pkg/constant/server_api_router.go | 4 +- testv2/config.go | 8 +- testv2/sync2_test.go | 47 ++++++++- 7 files changed, 259 insertions(+), 41 deletions(-) create mode 100644 internal/group/sync2.go diff --git a/internal/group/sdk.go b/internal/group/sdk.go index b54c45323..e79512d50 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -24,7 +24,6 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" - pconstant "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/log" "github.com/openimsdk/protocol/group" @@ -347,24 +346,24 @@ func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { return false, nil } -func (g *Group) SearchGroupMembersV2(ctx context.Context, req *group.SearchGroupMemberReq) ([]*model_struct.LocalGroupMember, error) { - if err := req.Check(); err != nil { - return nil, err - } - info, err := g.db.GetGroupInfoByGroupID(ctx, req.GroupID) - if err != nil { - return nil, err - } - if info.MemberCount <= pconstant.MaxSyncPullNumber { - return g.db.SearchGroupMembersDB(ctx, req.Keyword, req.GroupID, true, false, - int((req.Pagination.PageNumber-1)*req.Pagination.ShowNumber), int(req.Pagination.ShowNumber)) - } - resp, err := util.CallApi[group.SearchGroupMemberResp](ctx, constant.SearchGroupMember, req) - if err != nil { - return nil, err - } - return datautil.Slice(resp.Members, g.pbGroupMemberToLocal), nil -} +//func (g *Group) SearchGroupMembersV2(ctx context.Context, req *group.SearchGroupMemberReq) ([]*model_struct.LocalGroupMember, error) { +// if err := req.Check(); err != nil { +// return nil, err +// } +// info, err := g.db.GetGroupInfoByGroupID(ctx, req.GroupID) +// if err != nil { +// return nil, err +// } +// if info.MemberCount <= pconstant.MaxSyncPullNumber { +// return g.db.SearchGroupMembersDB(ctx, req.Keyword, req.GroupID, true, false, +// int((req.Pagination.PageNumber-1)*req.Pagination.ShowNumber), int(req.Pagination.ShowNumber)) +// } +// resp, err := util.CallApi[group.SearchGroupMemberResp](ctx, constant.SearchGroupMember, req) +// if err != nil { +// return nil, err +// } +// return datautil.Slice(resp.Members, g.pbGroupMemberToLocal), nil +//} func (g *Group) pbGroupMemberToLocal(pb *sdkws.GroupMemberFullInfo) *model_struct.LocalGroupMember { return &model_struct.LocalGroupMember{ diff --git a/internal/group/sync.go b/internal/group/sync.go index 71dadc042..5a99f110c 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -166,6 +166,7 @@ func (g *Group) deleteGroup(ctx context.Context, groupID string) error { } func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { + return nil _, err := g.syncAllJoinedGroups(ctx) if err != nil { return err diff --git a/internal/group/sync2.go b/internal/group/sync2.go new file mode 100644 index 000000000..0c84fb046 --- /dev/null +++ b/internal/group/sync2.go @@ -0,0 +1,164 @@ +package group + +import ( + "context" + "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" +) + +func (g *Group) getIncrementalGroupMemberBatch(ctx context.Context, groups []*group.GetIncrementalGroupMemberReq) (map[string]*group.GetIncrementalGroupMemberResp, error) { + type BatchIncrementalReq struct { + UserID string `json:"user_id"` + List []*group.GetIncrementalGroupMemberReq `json:"list"` + } + type BatchIncrementalResp struct { + List map[string]*group.GetIncrementalGroupMemberResp `json:"list"` + } + resp, err := util.CallApi[BatchIncrementalResp](ctx, constant.GetIncrementalGroupMemberBatch, &BatchIncrementalReq{UserID: g.loginUserID, List: groups}) + if err != nil { + return nil, err + } + return resp.List, nil +} + +func (g *Group) groupMemberVersionKey(groupID string) string { + return "friend:" + groupID +} + +func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { + groups, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + groupIDs := datautil.Slice(groups, func(e *model_struct.LocalGroup) string { + return e.GroupID + }) + return g.IncrSyncGroupMember(ctx, groupIDs) +} + +func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs []string) error { + if len(groupIDs) == 0 { + return nil + } + const maxSyncNum = 500 + groupIDSet := datautil.SliceSet(groupIDs) + var groups []*group.GetIncrementalGroupMemberReq + if len(groupIDs) > maxSyncNum { + groups = make([]*group.GetIncrementalGroupMemberReq, 0, maxSyncNum) + } else { + groups = make([]*group.GetIncrementalGroupMemberReq, 0, len(groupIDs)) + } + for { + if len(groupIDSet) == 0 { + return nil + } + for groupID := range groupIDSet { + if len(groups) == cap(groups) { + break + } + req := group.GetIncrementalGroupMemberReq{ + GroupID: groupID, + } + lvs, err := g.db.GetVersionSync(ctx, g.groupMemberVersionKey(groupID)) + if err == nil { + req.VersionID = lvs.VersionID + req.Version = lvs.Version + } else { + log.ZInfo(ctx, "get group version", "groupID", groupID, "error", err) + } + groups = append(groups, &req) + } + groupVersion, err := g.getIncrementalGroupMemberBatch(ctx, groups) + if err != nil { + return err + } + groups = groups[:0] + for groupID, resp := range groupVersion { + if err := g.syncGroupMember(ctx, groupID, resp); err != nil { + return err + } + delete(groupIDSet, groupID) + } + } +} + +func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group.GetIncrementalGroupMemberResp) error { + opt := incrversion.Option[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ + Ctx: ctx, + DB: g.db, + Key: func(localFriend *model_struct.LocalGroupMember) string { + return localFriend.UserID + }, + SyncKey: func() string { + return g.groupMemberVersionKey(groupID) + }, + Local: func() ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) + }, + ServerVersion: func() *group.GetIncrementalGroupMemberResp { + return resp + }, + Full: func(resp *group.GetIncrementalGroupMemberResp) bool { + return resp.Full + }, + Version: func(resp *group.GetIncrementalGroupMemberResp) (string, uint64) { + return resp.VersionID, resp.Version + }, + DeleteIDs: func(resp *group.GetIncrementalGroupMemberResp) []string { + return resp.DeleteUserIds + }, + Changes: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { + return util.Batch(ServerGroupMemberToLocalGroupMember, resp.Changes) + }, + Syncer: func(server, local []*model_struct.LocalGroupMember) error { + return g.groupMemberSyncer.Sync(ctx, server, local, nil) + }, + } + return opt.Sync() +} + +func (g *Group) groupJoinVersionKey() string { + return "join_group:" + g.loginUserID +} + +func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { + opt := incrversion.Option[*model_struct.LocalGroup, *group.GetIncrementalJoinGroupResp]{ + Ctx: ctx, + DB: g.db, + Key: func(localFriend *model_struct.LocalGroup) string { + return localFriend.GroupID + }, + SyncKey: g.groupJoinVersionKey, + Local: func() ([]*model_struct.LocalGroup, error) { + return g.db.GetJoinedGroupListDB(ctx) + }, + Server: func(version *model_struct.LocalVersionSync) (*group.GetIncrementalJoinGroupResp, error) { + return util.CallApi[group.GetIncrementalJoinGroupResp](ctx, constant.GetIncrementalJoinGroup, &group.GetIncrementalJoinGroupReq{ + UserID: g.loginUserID, + Version: version.Version, + VersionID: version.VersionID, + }) + }, + Full: func(resp *group.GetIncrementalJoinGroupResp) bool { + return resp.Full + }, + Version: func(resp *group.GetIncrementalJoinGroupResp) (string, uint64) { + return resp.VersionID, resp.Version + }, + DeleteIDs: func(resp *group.GetIncrementalJoinGroupResp) []string { + return resp.DeleteGroupIds + }, + Changes: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { + return util.Batch(ServerGroupToLocalGroup, resp.Changes) + }, + Syncer: func(server, local []*model_struct.LocalGroup) error { + return g.groupSyncer.Sync(ctx, server, local, nil) + }, + } + return opt.Sync() +} diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index f54ab7168..c4e20ca83 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -10,17 +10,18 @@ import ( ) type Option[V, R any] struct { - Ctx context.Context - DB db_interface.VersionSyncModel - Key func(V) string - SyncKey func() string - Local func() ([]V, error) - Server func(version *model_struct.LocalVersionSync) (R, error) - Full func(resp R) bool - Version func(resp R) (string, uint64) - DeleteIDs func(resp R) []string - Changes func(resp R) []V - Syncer func(server, local []V) error + Ctx context.Context + DB db_interface.VersionSyncModel + Key func(V) string + SyncKey func() string + Local func() ([]V, error) + ServerVersion func() R + Server func(version *model_struct.LocalVersionSync) (R, error) + Full func(resp R) bool + Version func(resp R) (string, uint64) + DeleteIDs func(resp R) []string + Changes func(resp R) []V + Syncer func(server, local []V) error } func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { @@ -36,16 +37,22 @@ func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { } func (o *Option[V, R]) Sync() error { - versionInfo := o.getVersionInfo() - resp, err := o.Server(versionInfo) - if err != nil { - return err + var resp R + if o.ServerVersion == nil { + version := o.getVersionInfo() + var err error + resp, err = o.Server(version) + if err != nil { + return err + } + } else { + resp = o.ServerVersion() } delIDs := o.DeleteIDs(resp) changes := o.Changes(resp) updateVersionInfo := func() error { lvs := &model_struct.LocalVersionSync{ - Key: versionInfo.Key, + Key: o.SyncKey(), CreateTime: time.Now().UnixMilli(), } lvs.VersionID, lvs.Version = o.Version(resp) diff --git a/pkg/constant/server_api_router.go b/pkg/constant/server_api_router.go index 8d20e99c5..1b1c602fd 100644 --- a/pkg/constant/server_api_router.go +++ b/pkg/constant/server_api_router.go @@ -104,7 +104,9 @@ const ( SetGroupMemberNicknameRouter = RouterGroup + "/set_group_member_nickname" SetGroupMemberInfoRouter = RouterGroup + "/set_group_member_info" GetGroupAbstractInfoRouter = RouterGroup + "/get_group_abstract_info" - SearchGroupMember = RouterGroup + "/search_group_member" + //SearchGroupMember = RouterGroup + "/search_group_member" + GetIncrementalJoinGroup = RouterGroup + "/get_incremental_join_group" + GetIncrementalGroupMemberBatch = RouterGroup + "/get_incremental_group_member_batch" SetReceiveMessageOptRouter = "/conversation/set_receive_message_opt" GetReceiveMessageOptRouter = "/conversation/get_receive_message_opt" diff --git a/testv2/config.go b/testv2/config.go index 1f8c8582c..073dce8c4 100644 --- a/testv2/config.go +++ b/testv2/config.go @@ -20,8 +20,12 @@ import ( ) const ( - APIADDR = "http://172.16.8.48:10002" - WSADDR = "ws://172.16.8.48:10001" + //APIADDR = "http://172.16.8.48:10002" + //WSADDR = "ws://172.16.8.48:10001" + + APIADDR = "http://127.0.0.1:10002" + WSADDR = "ws://127.0.0.1:10001" + UserID = "6864873394" friendUserID = "3281432310" ) diff --git a/testv2/sync2_test.go b/testv2/sync2_test.go index 83c40e9b5..d476bd8f4 100644 --- a/testv2/sync2_test.go +++ b/testv2/sync2_test.go @@ -15,16 +15,57 @@ package testv2 import ( + "fmt" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" + "github.com/openimsdk/protocol/constant" + "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" "testing" + "time" ) func TestSyncFriend2(t *testing.T) { for i := 0; ; i++ { if err := open_im_sdk.UserForSDK.Friend().IncrSyncFriends(ctx); err != nil { - t.Log("error-->", err) - //panic(err) + t.Log("IncrSyncFriends error-->", err) + continue + } + time.Sleep(time.Second) + } +} + +func TestSyncJoinGroup2(t *testing.T) { + for i := 0; ; i++ { + if err := open_im_sdk.UserForSDK.Group().IncrSyncJoinGroup(ctx); err != nil { + t.Log("IncrSyncJoinGroup error-->", err) + continue + } + time.Sleep(time.Second) + } +} + +func TestSyncGroupMember2(t *testing.T) { + for i := 0; ; i++ { + if err := open_im_sdk.UserForSDK.Group().IncrSyncJoinGroupMember(ctx); err != nil { + t.Log("IncrSyncGroupMember error-->", err) + continue + } + time.Sleep(time.Second) + } +} + +func TestName(t *testing.T) { + for i := 1; i <= 600; i++ { + _, err := open_im_sdk.UserForSDK.Group().CreateGroup(ctx, &group.CreateGroupReq{ + GroupInfo: &sdkws.GroupInfo{ + GroupType: constant.WorkingGroup, + GroupName: fmt.Sprintf("group_%d", i), + }, + MemberUserIDs: []string{"9556972319", "9719689061", "3872159645"}, + }) + if err != nil { + log.ZError(ctx, "group create failed", err, "index", i) } } - //select {} } From a945984f6f13c563e28f034770e7260448c60679 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Wed, 5 Jun 2024 17:50:22 +0800 Subject: [PATCH 07/69] sync --- go.mod | 8 +- go.sum | 4 +- internal/friend/conversion.go | 18 --- internal/friend/sdk.go | 2 +- internal/friend/sync.go | 74 +++++----- internal/friend/sync2.go | 4 +- internal/group/sync.go | 235 ++++++++++++++++--------------- internal/group/sync2.go | 9 +- msgtest/module/friend_manager.go | 2 - testv2/friend_test.go | 2 +- 10 files changed, 171 insertions(+), 187 deletions(-) diff --git a/go.mod b/go.mod index b68d1aa5c..05c067405 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/openimsdk/openim-sdk-core/v3 go 1.21 -toolchain go1.22.0 - require ( github.com/golang/protobuf v1.5.4 github.com/gorilla/websocket v1.4.2 @@ -19,7 +17,7 @@ require golang.org/x/net v0.22.0 require ( github.com/google/go-cmp v0.6.0 - github.com/openimsdk/protocol v0.0.69-alpha.3 + github.com/openimsdk/protocol v0.0.69-alpha.6 github.com/openimsdk/tools v0.0.49-alpha.9 github.com/patrickmn/go-cache v2.1.0+incompatible go.etcd.io/etcd/api/v3 v3.5.13 @@ -42,6 +40,4 @@ require ( google.golang.org/grpc v1.62.1 // indirect ) -//replace ( -// github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol -//) +//replace github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol diff --git a/go.sum b/go.sum index d79781630..288ed1695 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/openimsdk/protocol v0.0.69-alpha.3 h1:Uf167FVB5EqYpiy2zBbR63OiK+Njjy99fXYasK6Zi+4= -github.com/openimsdk/protocol v0.0.69-alpha.3/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= +github.com/openimsdk/protocol v0.0.69-alpha.6 h1:x7u1RqQPEXx+pphOSsDQXTqJVRvOuQkVfwbNfldwR1o= +github.com/openimsdk/protocol v0.0.69-alpha.6/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= github.com/openimsdk/tools v0.0.49-alpha.9 h1:yoa3GS6t0d1mRv/S86niFBGDgSjy2EWWwBI5NAH1Kgk= github.com/openimsdk/tools v0.0.49-alpha.9/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= diff --git a/internal/friend/conversion.go b/internal/friend/conversion.go index ec16aae18..0466bb449 100644 --- a/internal/friend/conversion.go +++ b/internal/friend/conversion.go @@ -16,8 +16,6 @@ package friend import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/protocol/friend" - "github.com/openimsdk/protocol/sdkws" ) @@ -71,19 +69,3 @@ func ServerBlackToLocalBlack(info *sdkws.BlackInfo) *model_struct.LocalBlack { //AttachedInfo: info.FriendUser.AttachedInfo, } } - -func ServerFriendToLocalFriendV2(info *friend.FriendInfo) *model_struct.LocalFriend { - return &model_struct.LocalFriend{ - OwnerUserID: info.OwnerUserID, - FriendUserID: info.FriendUserID, - Remark: info.Remark, - CreateTime: info.CreateTime, - AddSource: info.AddSource, - OperatorUserID: info.OperatorUserID, - Nickname: info.FriendNickname, - FaceURL: info.FriendFaceURL, - Ex: info.Ex, - //AttachedInfo: info.FriendUser.AttachedInfo, - IsPinned: info.IsPinned, - } -} diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index fcf345cf5..e1904be98 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -22,10 +22,10 @@ import ( sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" + friend "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/wrapperspb" "github.com/openimsdk/tools/errs" - "github.com/openimsdk/protocol/friend" "github.com/openimsdk/tools/log" ) diff --git a/internal/friend/sync.go b/internal/friend/sync.go index 3ac4aa9f7..e70d091bb 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -18,8 +18,7 @@ import ( "context" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" - "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" - "github.com/openimsdk/protocol/friend" + friend "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" ) @@ -74,46 +73,49 @@ func (f *Friend) SyncAllFriendApplication(ctx context.Context) error { } func (f *Friend) SyncAllFriendList(ctx context.Context) error { - req := &friend.GetPaginationFriendsReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} - fn := func(resp *friend.GetPaginationFriendsResp) []*sdkws.FriendInfo { return resp.FriendsInfo } - friends, err := util.GetPageAll(ctx, constant.GetFriendListRouter, req, fn) - if err != nil { - return err - } - localData, err := f.db.GetAllFriendList(ctx) - if err != nil { - return err - } - log.ZDebug(ctx, "sync friend", "data from server", friends, "data from local", localData) - return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, friends), localData, nil) + return f.IncrSyncFriends(ctx) + //req := &friend.GetPaginationFriendsReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} + //fn := func(resp *friend.GetPaginationFriendsResp) []*sdkws.FriendInfo { return resp.FriendsInfo } + //friends, err := util.GetPageAll(ctx, constant.GetFriendListRouter, req, fn) + //if err != nil { + // return err + //} + //localData, err := f.db.GetAllFriendList(ctx) + //if err != nil { + // return err + //} + //log.ZDebug(ctx, "sync friend", "data from server", friends, "data from local", localData) + //return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, friends), localData, nil) } func (f *Friend) deleteFriend(ctx context.Context, friendUserID string) error { - friends, err := f.db.GetFriendInfoList(ctx, []string{friendUserID}) - if err != nil { - return err - } - if len(friends) == 0 { - return sdkerrs.ErrUserIDNotFound.WrapMsg("friendUserID not found") - } - if err := f.db.DeleteFriendDB(ctx, friendUserID); err != nil { - return err - } - f.friendListener.OnFriendDeleted(*friends[0]) - return nil + return f.IncrSyncFriends(ctx) + //friends, err := f.db.GetFriendInfoList(ctx, []string{friendUserID}) + //if err != nil { + // return err + //} + //if len(friends) == 0 { + // return sdkerrs.ErrUserIDNotFound.WrapMsg("friendUserID not found") + //} + //if err := f.db.DeleteFriendDB(ctx, friendUserID); err != nil { + // return err + //} + //f.friendListener.OnFriendDeleted(*friends[0]) + //return nil } func (f *Friend) SyncFriends(ctx context.Context, friendIDs []string) error { - var resp friend.GetDesignatedFriendsResp - if err := util.ApiPost(ctx, constant.GetDesignatedFriendsRouter, &friend.GetDesignatedFriendsReq{OwnerUserID: f.loginUserID, FriendUserIDs: friendIDs}, &resp); err != nil { - return err - } - localData, err := f.db.GetFriendInfoList(ctx, friendIDs) - if err != nil { - return err - } - log.ZDebug(ctx, "sync friend", "data from server", resp.FriendsInfo, "data from local", localData) - return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo), localData, nil) + return f.IncrSyncFriends(ctx) + //var resp friend.GetDesignatedFriendsResp + //if err := util.ApiPost(ctx, constant.GetDesignatedFriendsRouter, &friend.GetDesignatedFriendsReq{OwnerUserID: f.loginUserID, FriendUserIDs: friendIDs}, &resp); err != nil { + // return err + //} + //localData, err := f.db.GetFriendInfoList(ctx, friendIDs) + //if err != nil { + // return err + //} + //log.ZDebug(ctx, "sync friend", "data from server", resp.FriendsInfo, "data from local", localData) + //return f.friendSyncer.Sync(ctx, util.Batch(ServerFriendToLocalFriend, resp.FriendsInfo), localData, nil) } //func (f *Friend) SyncFriendPart(ctx context.Context) error { diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index 04070a01c..59949dc51 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -6,7 +6,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/protocol/friend" + friend "github.com/openimsdk/protocol/relation" ) func (f *Friend) IncrSyncFriends(ctx context.Context) error { @@ -39,7 +39,7 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { return resp.DeleteUserIds }, Changes: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { - return util.Batch(ServerFriendToLocalFriendV2, resp.Changes) + return util.Batch(ServerFriendToLocalFriend, resp.Changes) }, Syncer: func(server, local []*model_struct.LocalFriend) error { return f.friendSyncer.Sync(ctx, server, local, nil) diff --git a/internal/group/sync.go b/internal/group/sync.go index 5a99f110c..c6a2e5330 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -16,71 +16,67 @@ package group import ( "context" - "crypto/md5" - "encoding/binary" "encoding/json" "errors" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" - "github.com/openimsdk/tools/utils/datautil" - "sync" ) -func (g *Group) getGroupHash(members []*model_struct.LocalGroupMember) uint64 { - userIDs := datautil.Slice(members, func(member *model_struct.LocalGroupMember) string { - return member.UserID - }) - datautil.Sort(userIDs, true) - memberMap := make(map[string]*sdkws.GroupMemberFullInfo) - for _, member := range members { - memberMap[member.UserID] = &sdkws.GroupMemberFullInfo{ - GroupID: member.GroupID, - UserID: member.UserID, - RoleLevel: member.RoleLevel, - JoinTime: member.JoinTime, - Nickname: member.Nickname, - FaceURL: member.FaceURL, - AppMangerLevel: 0, - JoinSource: member.JoinSource, - OperatorUserID: member.OperatorUserID, - Ex: member.Ex, - MuteEndTime: member.MuteEndTime, - InviterUserID: member.InviterUserID, - } - } - res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) - for _, userID := range userIDs { - res = append(res, memberMap[userID]) - } - val, _ := json.Marshal(res) - sum := md5.Sum(val) - return binary.BigEndian.Uint64(sum[:]) -} +//func (g *Group) getGroupHash(members []*model_struct.LocalGroupMember) uint64 { +// userIDs := datautil.Slice(members, func(member *model_struct.LocalGroupMember) string { +// return member.UserID +// }) +// datautil.Sort(userIDs, true) +// memberMap := make(map[string]*sdkws.GroupMemberFullInfo) +// for _, member := range members { +// memberMap[member.UserID] = &sdkws.GroupMemberFullInfo{ +// GroupID: member.GroupID, +// UserID: member.UserID, +// RoleLevel: member.RoleLevel, +// JoinTime: member.JoinTime, +// Nickname: member.Nickname, +// FaceURL: member.FaceURL, +// AppMangerLevel: 0, +// JoinSource: member.JoinSource, +// OperatorUserID: member.OperatorUserID, +// Ex: member.Ex, +// MuteEndTime: member.MuteEndTime, +// InviterUserID: member.InviterUserID, +// } +// } +// res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) +// for _, userID := range userIDs { +// res = append(res, memberMap[userID]) +// } +// val, _ := json.Marshal(res) +// sum := md5.Sum(val) +// return binary.BigEndian.Uint64(sum[:]) +//} func (g *Group) SyncAllGroupMember(ctx context.Context, groupID string) error { - absInfo, err := g.GetGroupAbstractInfo(ctx, groupID) - if err != nil { - return err - } - localData, err := g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) - if err != nil { - return err - } - hashCode := g.getGroupHash(localData) - if len(localData) == int(absInfo.GroupMemberNumber) && hashCode == absInfo.GroupMemberListHash { - log.ZDebug(ctx, "SyncAllGroupMember no change in personnel", "groupID", groupID, "hashCode", hashCode, "absInfo.GroupMemberListHash", absInfo.GroupMemberListHash) - return nil - } - members, err := g.GetServerGroupMembers(ctx, groupID) - if err != nil { - return err - } - return g.syncGroupMembers(ctx, groupID, members, localData) + return g.IncrSyncGroupMember(ctx, groupID) + //absInfo, err := g.GetGroupAbstractInfo(ctx, groupID) + //if err != nil { + // return err + //} + //localData, err := g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) + //if err != nil { + // return err + //} + //hashCode := g.getGroupHash(localData) + //if len(localData) == int(absInfo.GroupMemberNumber) && hashCode == absInfo.GroupMemberListHash { + // log.ZDebug(ctx, "SyncAllGroupMember no change in personnel", "groupID", groupID, "hashCode", hashCode, "absInfo.GroupMemberListHash", absInfo.GroupMemberListHash) + // return nil + //} + //members, err := g.GetServerGroupMembers(ctx, groupID) + //if err != nil { + // return err + //} + //return g.syncGroupMembers(ctx, groupID, members, localData) } func (g *Group) syncGroupMembers(ctx context.Context, groupID string, members []*sdkws.GroupMemberFullInfo, localData []*model_struct.LocalGroupMember) error { @@ -127,82 +123,89 @@ func (g *Group) syncGroupMembers(ctx context.Context, groupID string, members [] } func (g *Group) SyncGroupMembers(ctx context.Context, groupID string, userIDs ...string) error { - members, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) - if err != nil { - return err - } - localData, err := g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDs) - if err != nil { - return err - } - return g.syncGroupMembers(ctx, groupID, members, localData) + return g.IncrSyncGroupMember(ctx, groupID) + //members, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + //if err != nil { + // return err + //} + //localData, err := g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDs) + //if err != nil { + // return err + //} + //return g.syncGroupMembers(ctx, groupID, members, localData) } func (g *Group) SyncGroups(ctx context.Context, groupIDs ...string) error { - groups, err := g.getGroupsInfoFromSvr(ctx, groupIDs) - if err != nil { - return err - } - localData, err := g.db.GetGroups(ctx, groupIDs) - if err != nil { - return err - } - if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { - return err - } - return nil + return g.IncrSyncJoinGroup(ctx) + //groups, err := g.getGroupsInfoFromSvr(ctx, groupIDs) + //if err != nil { + // return err + //} + //localData, err := g.db.GetGroups(ctx, groupIDs) + //if err != nil { + // return err + //} + //if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { + // return err + //} + //return nil } func (g *Group) deleteGroup(ctx context.Context, groupID string) error { - groupInfo, err := g.db.GetGroupInfoByGroupID(ctx, groupID) - if err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, groupID); err != nil { - return err - } - g.listener().OnJoinedGroupDeleted(utils.StructToJsonString(groupInfo)) - return nil + return g.IncrSyncJoinGroup(ctx) + //groupInfo, err := g.db.GetGroupInfoByGroupID(ctx, groupID) + //if err != nil { + // return err + //} + //if err := g.db.DeleteGroup(ctx, groupID); err != nil { + // return err + //} + //g.listener().OnJoinedGroupDeleted(utils.StructToJsonString(groupInfo)) + //return nil } func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { - return nil - _, err := g.syncAllJoinedGroups(ctx) - if err != nil { - return err - } - groups, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { + if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - var wg sync.WaitGroup - for _, group := range groups { - wg.Add(1) - go func(groupID string) { - defer wg.Done() - if err := g.SyncAllGroupMember(ctx, groupID); err != nil { - log.ZError(ctx, "SyncGroupMember failed", err) - } - }(group.GroupID) - } - wg.Wait() - return nil -} -func (g *Group) syncAllJoinedGroups(ctx context.Context) ([]*sdkws.GroupInfo, error) { - groups, err := g.GetServerJoinGroup(ctx) - if err != nil { - return nil, err - } - localData, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return nil, err - } - if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { - return nil, err - } - return groups, nil + return g.IncrSyncJoinGroupMember(ctx) + //_, err := g.syncAllJoinedGroups(ctx) + //if err != nil { + // return err + //} + //groups, err := g.db.GetJoinedGroupListDB(ctx) + //if err != nil { + // return err + //} + //var wg sync.WaitGroup + //for _, group := range groups { + // wg.Add(1) + // go func(groupID string) { + // defer wg.Done() + // if err := g.SyncAllGroupMember(ctx, groupID); err != nil { + // log.ZError(ctx, "SyncGroupMember failed", err) + // } + // }(group.GroupID) + //} + //wg.Wait() + //return nil } +//func (g *Group) syncAllJoinedGroups(ctx context.Context) ([]*sdkws.GroupInfo, error) { +// groups, err := g.GetServerJoinGroup(ctx) +// if err != nil { +// return nil, err +// } +// localData, err := g.db.GetJoinedGroupListDB(ctx) +// if err != nil { +// return nil, err +// } +// if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { +// return nil, err +// } +// return groups, nil +//} + func (g *Group) SyncAllSelfGroupApplication(ctx context.Context) error { list, err := g.GetServerSelfGroupApplication(ctx) if err != nil { diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 0c84fb046..07a6cd893 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -6,6 +6,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + pconstant "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/group" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" @@ -38,14 +39,14 @@ func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { groupIDs := datautil.Slice(groups, func(e *model_struct.LocalGroup) string { return e.GroupID }) - return g.IncrSyncGroupMember(ctx, groupIDs) + return g.IncrSyncGroupMember(ctx, groupIDs...) } -func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs []string) error { +func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) error { if len(groupIDs) == 0 { return nil } - const maxSyncNum = 500 + const maxSyncNum = pconstant.MaxSyncPullNumber groupIDSet := datautil.SliceSet(groupIDs) var groups []*group.GetIncrementalGroupMemberReq if len(groupIDs) > maxSyncNum { @@ -84,6 +85,8 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs []string) erro } delete(groupIDSet, groupID) } + num := len(groupIDSet) + _ = num } } diff --git a/msgtest/module/friend_manager.go b/msgtest/module/friend_manager.go index 2861f45e7..ab99b9f7a 100644 --- a/msgtest/module/friend_manager.go +++ b/msgtest/module/friend_manager.go @@ -2,8 +2,6 @@ package module import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" - - "github.com/openimsdk/protocol/friend" ) type TestFriendManager struct { diff --git a/testv2/friend_test.go b/testv2/friend_test.go index 0e794f84e..48292c6cb 100644 --- a/testv2/friend_test.go +++ b/testv2/friend_test.go @@ -21,7 +21,7 @@ import ( "testing" "time" - friend2 "github.com/openimsdk/protocol/friend" + friend2 "github.com/openimsdk/protocol/relation" ) func Test_GetSpecifiedFriendsInfo(t *testing.T) { From 31e53b37150d4cb16b87e7f895167dbbd08d5498 Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Sat, 15 Jun 2024 14:33:51 +0800 Subject: [PATCH 08/69] feat: group member full sync and incr sync. --- cmd/gordon_main.go | 2 +- go.mod | 2 +- go.sum | 4 +- internal/conversation_msg/conversation_msg.go | 4 +- .../conversation_notification.go | 19 +- internal/friend/friend.go | 16 +- internal/friend/sdk.go | 1 + internal/friend/sync2.go | 82 +++---- internal/friend/sync2_test.go | 13 ++ internal/group/group.go | 204 ++++++++++------- internal/group/notification.go | 3 +- internal/group/sync.go | 189 +++++++++------- internal/group/sync2.go | 201 +++++++++++++---- internal/group/sync2_test.go | 1 + internal/incrversion/option.go | 206 ++++++++++++++---- internal/user/user.go | 8 +- internal/util/notice.go | 30 +-- internal/util/post.go | 63 ++++++ pkg/constant/server_api_router.go | 2 + pkg/db/db_interface/databse.go | 5 +- pkg/db/friend_model.go | 8 + pkg/db/group_model.go | 13 ++ pkg/db/model_struct/data_model_struct.go | 38 +++- pkg/db/version_sync.go | 27 ++- pkg/page/pagereq.go | 7 + pkg/syncer/syncer.go | 202 +++++++++++++++-- test/account.go | 6 +- 27 files changed, 998 insertions(+), 358 deletions(-) create mode 100644 internal/friend/sync2_test.go create mode 100644 internal/group/sync2_test.go create mode 100644 pkg/page/pagereq.go diff --git a/cmd/gordon_main.go b/cmd/gordon_main.go index 949e7a33b..3db79a00f 100644 --- a/cmd/gordon_main.go +++ b/cmd/gordon_main.go @@ -93,7 +93,7 @@ func gRunGetToken(strMyUid string) string { return token } func main() { - uid := "1" + uid := "1695766238" //Gordon //uid:="1554321956297519104" //Gordon2 diff --git a/go.mod b/go.mod index 05c067405..0dbe44b37 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require golang.org/x/net v0.22.0 require ( github.com/google/go-cmp v0.6.0 - github.com/openimsdk/protocol v0.0.69-alpha.6 + github.com/openimsdk/protocol v0.0.69-alpha.9 github.com/openimsdk/tools v0.0.49-alpha.9 github.com/patrickmn/go-cache v2.1.0+incompatible go.etcd.io/etcd/api/v3 v3.5.13 diff --git a/go.sum b/go.sum index 288ed1695..cb4145599 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/openimsdk/protocol v0.0.69-alpha.6 h1:x7u1RqQPEXx+pphOSsDQXTqJVRvOuQkVfwbNfldwR1o= -github.com/openimsdk/protocol v0.0.69-alpha.6/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= +github.com/openimsdk/protocol v0.0.69-alpha.9 h1:Mh1upsxwhWs1y65cfIN2XuRsiKEk4MfpYfA9XrvtX24= +github.com/openimsdk/protocol v0.0.69-alpha.9/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= github.com/openimsdk/tools v0.0.49-alpha.9 h1:yoa3GS6t0d1mRv/S86niFBGDgSjy2EWWwBI5NAH1Kgk= github.com/openimsdk/tools v0.0.49-alpha.9/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= diff --git a/internal/conversation_msg/conversation_msg.go b/internal/conversation_msg/conversation_msg.go index fbfbd5481..6648e7e76 100644 --- a/internal/conversation_msg/conversation_msg.go +++ b/internal/conversation_msg/conversation_msg.go @@ -50,7 +50,7 @@ var SearchContentType = []int{constant.Text, constant.AtText, constant.File} type Conversation struct { *interaction.LongConnMgr - conversationSyncer *syncer.Syncer[*model_struct.LocalConversation, string] + conversationSyncer *syncer.Syncer[*model_struct.LocalConversation, syncer.NoResp, string] db db_interface.DataBase ConversationListener func() open_im_sdk_callback.OnConversationListener msgListener func() open_im_sdk_callback.OnAdvancedMsgListener @@ -115,7 +115,7 @@ func NewConversation(ctx context.Context, longConnMgr *interaction.LongConnMgr, } func (c *Conversation) initSyncer() { - c.conversationSyncer = syncer.New( + c.conversationSyncer = syncer.New[*model_struct.LocalConversation, syncer.NoResp, string]( func(ctx context.Context, value *model_struct.LocalConversation) error { return c.db.InsertConversation(ctx, value) }, diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index a8c4e9e30..925142f9c 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -620,15 +620,16 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } //clear SubscriptionStatusMap c.user.OnlineStatusCache.DeleteAll() - for _, syncFunc := range []func(c context.Context) error{ - c.user.SyncLoginUserInfo, - c.friend.SyncAllBlackList, c.friend.SyncAllFriendList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, - c.group.SyncAllJoinedGroupsAndMembers, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, - } { - go func(syncFunc func(c context.Context) error) { - _ = syncFunc(ctx) - }(syncFunc) - } + //for _, syncFunc := range []func(c context.Context) error{ + // c.user.SyncLoginUserInfo, + // c.friend.SyncAllBlackList, c.friend.SyncAllFriendList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, + // c.group.SyncAllJoinedGroupsAndMembers, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, + //} { + // go func(syncFunc func(c context.Context) error) { + // _ = syncFunc(ctx) + // }(syncFunc) + //} + c.group.SyncAllJoinedGroupsAndMembers2(ctx) case constant.MsgSyncFailed: c.ConversationListener().OnSyncServerFailed() case constant.MsgSyncEnd: diff --git a/internal/friend/friend.go b/internal/friend/friend.go index 5aa850678..3a8df9f32 100644 --- a/internal/friend/friend.go +++ b/internal/friend/friend.go @@ -41,16 +41,16 @@ type Friend struct { loginUserID string db db_interface.DataBase user *user.User - friendSyncer *syncer.Syncer[*model_struct.LocalFriend, [2]string] - blockSyncer *syncer.Syncer[*model_struct.LocalBlack, [2]string] - requestRecvSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, [2]string] - requestSendSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, [2]string] + friendSyncer *syncer.Syncer[*model_struct.LocalFriend, syncer.NoResp, [2]string] + blockSyncer *syncer.Syncer[*model_struct.LocalBlack, syncer.NoResp, [2]string] + requestRecvSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] + requestSendSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] conversationCh chan common.Cmd2Value listenerForService open_im_sdk_callback.OnListenerForService } func (f *Friend) initSyncer() { - f.friendSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalFriend) error { + f.friendSyncer = syncer.New[*model_struct.LocalFriend, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error { return f.db.InsertFriend(ctx, value) }, func(ctx context.Context, value *model_struct.LocalFriend) error { return f.db.DeleteFriendDB(ctx, value.FriendUserID) @@ -81,7 +81,7 @@ func (f *Friend) initSyncer() { } return nil }) - f.blockSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalBlack) error { + f.blockSyncer = syncer.New[*model_struct.LocalBlack, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalBlack) error { return f.db.InsertBlack(ctx, value) }, func(ctx context.Context, value *model_struct.LocalBlack) error { return f.db.DeleteBlack(ctx, value.BlockUserID) @@ -98,7 +98,7 @@ func (f *Friend) initSyncer() { } return nil }) - f.requestRecvSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalFriendRequest) error { + f.requestRecvSyncer = syncer.New[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriendRequest) error { return f.db.InsertFriendRequest(ctx, value) }, func(ctx context.Context, value *model_struct.LocalFriendRequest) error { return f.db.DeleteFriendRequestBothUserID(ctx, value.FromUserID, value.ToUserID) @@ -124,7 +124,7 @@ func (f *Friend) initSyncer() { } return nil }) - f.requestSendSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalFriendRequest) error { + f.requestSendSyncer = syncer.New[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriendRequest) error { return f.db.InsertFriendRequest(ctx, value) }, func(ctx context.Context, value *model_struct.LocalFriendRequest) error { return f.db.DeleteFriendRequestBothUserID(ctx, value.FromUserID, value.ToUserID) diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index e1904be98..f74530d63 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -82,6 +82,7 @@ func (f *Friend) RefuseFriendApplication(ctx context.Context, userIDHandleMsg *s } func (f *Friend) RespondFriendApply(ctx context.Context, req *friend.RespondFriendApplyReq) error { + if req.ToUserID == "" { req.ToUserID = f.loginUserID } diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index 59949dc51..29e4e84f2 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -2,48 +2,48 @@ package friend import ( "context" - "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" - "github.com/openimsdk/openim-sdk-core/v3/internal/util" - "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" - "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - friend "github.com/openimsdk/protocol/relation" +) + +const ( + LocalFriendSyncMaxNum = 1000 ) func (f *Friend) IncrSyncFriends(ctx context.Context) error { - opt := incrversion.Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ - Ctx: ctx, - DB: f.db, - Key: func(localFriend *model_struct.LocalFriend) string { - return localFriend.FriendUserID - }, - SyncKey: func() string { - return "friend:" + f.loginUserID - }, - Local: func() ([]*model_struct.LocalFriend, error) { - return f.db.GetAllFriendList(ctx) - }, - Server: func(version *model_struct.LocalVersionSync) (*friend.GetIncrementalFriendsResp, error) { - return util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, &friend.GetIncrementalFriendsReq{ - UserID: f.loginUserID, - Version: version.Version, - VersionID: version.VersionID, - }) - }, - Full: func(resp *friend.GetIncrementalFriendsResp) bool { - return resp.Full - }, - Version: func(resp *friend.GetIncrementalFriendsResp) (string, uint64) { - return resp.VersionID, resp.Version - }, - DeleteIDs: func(resp *friend.GetIncrementalFriendsResp) []string { - return resp.DeleteUserIds - }, - Changes: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { - return util.Batch(ServerFriendToLocalFriend, resp.Changes) - }, - Syncer: func(server, local []*model_struct.LocalFriend) error { - return f.friendSyncer.Sync(ctx, server, local, nil) - }, - } - return opt.Sync() + //opt := incrversion.Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ + // Ctx: ctx, + // DB: f.db, + // Key: func(localFriend *model_struct.LocalFriend) string { + // return localFriend.FriendUserID + // }, + // SyncKey: func() string { + // return "friend:" + f.loginUserID + // }, + // Local: func() ([]*model_struct.LocalFriend, error) { + // return f.db.GetAllFriendList(ctx) + // }, + // Server: func(version *model_struct.LocalVersionSync) (*friend.GetIncrementalFriendsResp, error) { + // return util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, &friend.GetIncrementalFriendsReq{ + // UserID: f.loginUserID, + // Version: version.Version, + // VersionID: version.VersionID, + // }) + // }, + // Full: func(resp *friend.GetIncrementalFriendsResp) bool { + // return resp.Full + // }, + // Version: func(resp *friend.GetIncrementalFriendsResp) (string, uint64) { + // return resp.VersionID, resp.Version + // }, + // DeleteIDs: func(resp *friend.GetIncrementalFriendsResp) []string { + // return resp.DeleteUserIds + // }, + // Changes: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { + // return util.Batch(ServerFriendToLocalFriend, resp.Changes) + // }, + // Syncer: func(server, local []*model_struct.LocalFriend) error { + // return f.friendSyncer.Sync(ctx, server, local, nil) + // }, + //} + //return opt.Sync() + return nil } diff --git a/internal/friend/sync2_test.go b/internal/friend/sync2_test.go new file mode 100644 index 000000000..d782b69b0 --- /dev/null +++ b/internal/friend/sync2_test.go @@ -0,0 +1,13 @@ +package friend + +import ( + "fmt" + "testing" +) + +func Test_main(t *testing.T) { + a := []int{1, 2, 3, 4, 5} + fmt.Println(a[:3]) + fmt.Println(a[3:]) + fmt.Println(a[2:4]) +} diff --git a/internal/group/group.go b/internal/group/group.go index 031cc15b6..3d33bfac9 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -22,6 +22,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/openim-sdk-core/v3/pkg/page" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" @@ -47,10 +48,10 @@ type Group struct { listener func() open_im_sdk_callback.OnGroupListener loginUserID string db db_interface.DataBase - groupSyncer *syncer.Syncer[*model_struct.LocalGroup, string] - groupMemberSyncer *syncer.Syncer[*model_struct.LocalGroupMember, [2]string] - groupRequestSyncer *syncer.Syncer[*model_struct.LocalGroupRequest, [2]string] - groupAdminRequestSyncer *syncer.Syncer[*model_struct.LocalAdminGroupRequest, [2]string] + groupSyncer *syncer.Syncer[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string] + groupMemberSyncer *syncer.Syncer[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string] + groupRequestSyncer *syncer.Syncer[*model_struct.LocalGroupRequest, syncer.NoResp, [2]string] + groupAdminRequestSyncer *syncer.Syncer[*model_struct.LocalAdminGroupRequest, syncer.NoResp, [2]string] joinedSuperGroupCh chan common.Cmd2Value heartbeatCmdCh chan common.Cmd2Value @@ -61,81 +62,136 @@ type Group struct { } func (g *Group) initSyncer() { - g.groupSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalGroup) error { - return g.db.InsertGroup(ctx, value) - }, func(ctx context.Context, value *model_struct.LocalGroup) error { - if err := g.db.DeleteGroupAllMembers(ctx, value.GroupID); err != nil { - return err - } - return g.db.DeleteGroup(ctx, value.GroupID) - }, func(ctx context.Context, server, local *model_struct.LocalGroup) error { - log.ZInfo(ctx, "groupSyncer trigger update function", "groupID", server.GroupID, "server", server, "local", local) - return g.db.UpdateGroup(ctx, server) - }, func(value *model_struct.LocalGroup) string { - return value.GroupID - }, nil, func(ctx context.Context, state int, server, local *model_struct.LocalGroup) error { - switch state { - case syncer.Insert: - //when a user kicked to the group and invited to the group again, group info maybe updated,so conversation - //info need to be updated - g.listener().OnJoinedGroupAdded(utils.StructToJsonString(server)) - _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.UpdateConFaceUrlAndNickName, - Args: common.SourceIDAndSessionType{SourceID: server.GroupID, SessionType: constant.SuperGroupChatType, - FaceURL: server.FaceURL, Nickname: server.GroupName}}, g.conversationCh) - case syncer.Delete: - g.listener().OnJoinedGroupDeleted(utils.StructToJsonString(local)) - case syncer.Update: - log.ZInfo(ctx, "groupSyncer trigger update", "groupID", - server.GroupID, "data", server, "isDismissed", server.Status == constant.GroupStatusDismissed) - if server.Status == constant.GroupStatusDismissed { - if err := g.db.DeleteGroupAllMembers(ctx, server.GroupID); err != nil { - log.ZError(ctx, "delete group all members failed", err) - } - g.listener().OnGroupDismissed(utils.StructToJsonString(server)) - } else { - g.listener().OnGroupInfoChanged(utils.StructToJsonString(server)) - if server.GroupName != local.GroupName || local.FaceURL != server.FaceURL { - _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.UpdateConFaceUrlAndNickName, - Args: common.SourceIDAndSessionType{SourceID: server.GroupID, SessionType: constant.SuperGroupChatType, FaceURL: server.FaceURL, Nickname: server.GroupName}}, g.conversationCh) + g.groupSyncer = syncer.New2[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string]( + syncer.WithInsert[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, value *model_struct.LocalGroup) error { + return g.db.InsertGroup(ctx, value) + }), + syncer.WithDelete[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, value *model_struct.LocalGroup) error { + if err := g.db.DeleteGroupAllMembers(ctx, value.GroupID); err != nil { + return err + } + return g.db.DeleteGroup(ctx, value.GroupID) + }), + syncer.WithUpdate[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, server, local *model_struct.LocalGroup) error { + log.ZInfo(ctx, "groupSyncer trigger update function", "groupID", server.GroupID, "server", server, "local", local) + return g.db.UpdateGroup(ctx, server) + }), + syncer.WithUUID[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(value *model_struct.LocalGroup) string { + return value.GroupID + }), + syncer.WithNotice[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, state int, server, local *model_struct.LocalGroup) error { + switch state { + case syncer.Insert: + // when a user kicked to the group and invited to the group again, group info maybe updated, + // so conversation info need to be updated + g.listener().OnJoinedGroupAdded(utils.StructToJsonString(server)) + _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{ + Action: constant.UpdateConFaceUrlAndNickName, + Args: common.SourceIDAndSessionType{ + SourceID: server.GroupID, SessionType: constant.SuperGroupChatType, + FaceURL: server.FaceURL, Nickname: server.GroupName, + }, + }, g.conversationCh) + case syncer.Delete: + g.listener().OnJoinedGroupDeleted(utils.StructToJsonString(local)) + case syncer.Update: + log.ZInfo(ctx, "groupSyncer trigger update", "groupID", + server.GroupID, "data", server, "isDismissed", server.Status == constant.GroupStatusDismissed) + if server.Status == constant.GroupStatusDismissed { + if err := g.db.DeleteGroupAllMembers(ctx, server.GroupID); err != nil { + log.ZError(ctx, "delete group all members failed", err) + } + g.listener().OnGroupDismissed(utils.StructToJsonString(server)) + } else { + g.listener().OnGroupInfoChanged(utils.StructToJsonString(server)) + if server.GroupName != local.GroupName || local.FaceURL != server.FaceURL { + _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{ + Action: constant.UpdateConFaceUrlAndNickName, + Args: common.SourceIDAndSessionType{ + SourceID: server.GroupID, SessionType: constant.SuperGroupChatType, + FaceURL: server.FaceURL, Nickname: server.GroupName, + }, + }, g.conversationCh) + } } } - } - - return nil - }) + return nil + }), + syncer.WithBatchInsert[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, values []*model_struct.LocalGroup) error { + return g.db.BatchInsertGroup(ctx, values) + }), + syncer.WithDeleteAll[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, _ string) error { + return g.db.DeleteAllGroup(ctx) + }), + syncer.WithBatchPageReq[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(entityID string) page.PageReq { + return &group.GetJoinedGroupListReq{FromUserID: entityID, + Pagination: &sdkws.RequestPagination{}} + }), + syncer.WithBatchPageRespConvertFunc[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(resp *group.GetJoinedGroupListResp) []*model_struct.LocalGroup { + return datautil.Batch(ServerGroupToLocalGroup, resp.Groups) + }), + syncer.WithReqApiRouter[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](constant.GetJoinedGroupListRouter), + ) - g.groupMemberSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalGroupMember) error { - return g.db.InsertGroupMember(ctx, value) - }, func(ctx context.Context, value *model_struct.LocalGroupMember) error { - return g.db.DeleteGroupMember(ctx, value.GroupID, value.UserID) - }, func(ctx context.Context, server, local *model_struct.LocalGroupMember) error { - return g.db.UpdateGroupMember(ctx, server) - }, func(value *model_struct.LocalGroupMember) [2]string { - return [...]string{value.GroupID, value.UserID} - }, nil, func(ctx context.Context, state int, server, local *model_struct.LocalGroupMember) error { - switch state { - case syncer.Insert: - g.listener().OnGroupMemberAdded(utils.StructToJsonString(server)) - //when a user kicked and invited to the group again, group member info will be updated - _ = common.TriggerCmdUpdateMessage(ctx, - common.UpdateMessageNode{Action: constant.UpdateMsgFaceUrlAndNickName, - Args: common.UpdateMessageInfo{SessionType: constant.SuperGroupChatType, UserID: server.UserID, FaceURL: server.FaceURL, - Nickname: server.Nickname, GroupID: server.GroupID}}, g.conversationCh) - case syncer.Delete: - g.listener().OnGroupMemberDeleted(utils.StructToJsonString(local)) - case syncer.Update: - g.listener().OnGroupMemberInfoChanged(utils.StructToJsonString(server)) - if server.Nickname != local.Nickname || server.FaceURL != local.FaceURL { + g.groupMemberSyncer = syncer.New2[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string]( + syncer.WithInsert[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, value *model_struct.LocalGroupMember) error { + return g.db.InsertGroupMember(ctx, value) + }), + syncer.WithDelete[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, value *model_struct.LocalGroupMember) error { + return g.db.DeleteGroupMember(ctx, value.GroupID, value.UserID) + }), + syncer.WithUpdate[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, server, local *model_struct.LocalGroupMember) error { + return g.db.UpdateGroupMember(ctx, server) + }), + syncer.WithUUID[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(value *model_struct.LocalGroupMember) [2]string { + return [...]string{value.GroupID, value.UserID} + }), + syncer.WithNotice[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, state int, server, local *model_struct.LocalGroupMember) error { + switch state { + case syncer.Insert: + g.listener().OnGroupMemberAdded(utils.StructToJsonString(server)) + // When a user is kicked and invited to the group again, group member info will be updated. _ = common.TriggerCmdUpdateMessage(ctx, - common.UpdateMessageNode{Action: constant.UpdateMsgFaceUrlAndNickName, - Args: common.UpdateMessageInfo{SessionType: constant.SuperGroupChatType, UserID: server.UserID, FaceURL: server.FaceURL, - Nickname: server.Nickname, GroupID: server.GroupID}}, g.conversationCh) + common.UpdateMessageNode{ + Action: constant.UpdateMsgFaceUrlAndNickName, + Args: common.UpdateMessageInfo{ + SessionType: constant.SuperGroupChatType, UserID: server.UserID, FaceURL: server.FaceURL, + Nickname: server.Nickname, GroupID: server.GroupID, + }, + }, g.conversationCh) + case syncer.Delete: + g.listener().OnGroupMemberDeleted(utils.StructToJsonString(local)) + case syncer.Update: + g.listener().OnGroupMemberInfoChanged(utils.StructToJsonString(server)) + if server.Nickname != local.Nickname || server.FaceURL != local.FaceURL { + _ = common.TriggerCmdUpdateMessage(ctx, + common.UpdateMessageNode{ + Action: constant.UpdateMsgFaceUrlAndNickName, + Args: common.UpdateMessageInfo{ + SessionType: constant.SuperGroupChatType, UserID: server.UserID, FaceURL: server.FaceURL, + Nickname: server.Nickname, GroupID: server.GroupID, + }, + }, g.conversationCh) + } } - } - return nil - }) + return nil + }), + syncer.WithBatchInsert[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }), + syncer.WithDeleteAll[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, entityID string) error { + return g.db.DeleteGroupAllMembers(ctx, entityID) + }), + syncer.WithBatchPageReq[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(entityID string) page.PageReq { + return &group.GetGroupMemberListReq{GroupID: entityID, Pagination: &sdkws.RequestPagination{ShowNumber: 100}} + }), + syncer.WithBatchPageRespConvertFunc[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(resp *group.GetGroupMemberListResp) []*model_struct.LocalGroupMember { + return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Members) + }), + syncer.WithReqApiRouter[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](constant.GetGroupMemberListRouter), + ) - g.groupRequestSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalGroupRequest) error { + g.groupRequestSyncer = syncer.New[*model_struct.LocalGroupRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalGroupRequest) error { return g.db.InsertGroupRequest(ctx, value) }, func(ctx context.Context, value *model_struct.LocalGroupRequest) error { return g.db.DeleteGroupRequest(ctx, value.GroupID, value.UserID) @@ -160,7 +216,7 @@ func (g *Group) initSyncer() { return nil }) - g.groupAdminRequestSyncer = syncer.New(func(ctx context.Context, value *model_struct.LocalAdminGroupRequest) error { + g.groupAdminRequestSyncer = syncer.New[*model_struct.LocalAdminGroupRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalAdminGroupRequest) error { return g.db.InsertAdminGroupRequest(ctx, value) }, func(ctx context.Context, value *model_struct.LocalAdminGroupRequest) error { return g.db.DeleteAdminGroupRequest(ctx, value.GroupID, value.UserID) diff --git a/internal/group/notification.go b/internal/group/notification.go index f699ff13b..9deae25fb 100644 --- a/internal/group/notification.go +++ b/internal/group/notification.go @@ -183,7 +183,8 @@ func (g *Group) doNotification(ctx context.Context, msg *sdkws.MsgData) error { g.listener().OnGroupInfoChanged(string(data)) return nil } else { - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) + //return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, nil, nil, detail.GroupMemberVersion) } case constant.MemberInvitedNotification: // 1509 var detail sdkws.MemberInvitedTips diff --git a/internal/group/sync.go b/internal/group/sync.go index c6a2e5330..8e839f6b3 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -16,67 +16,76 @@ package group import ( "context" + "crypto/md5" + "encoding/binary" "encoding/json" "errors" + "fmt" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" + "sync" + "time" ) -//func (g *Group) getGroupHash(members []*model_struct.LocalGroupMember) uint64 { -// userIDs := datautil.Slice(members, func(member *model_struct.LocalGroupMember) string { -// return member.UserID -// }) -// datautil.Sort(userIDs, true) -// memberMap := make(map[string]*sdkws.GroupMemberFullInfo) -// for _, member := range members { -// memberMap[member.UserID] = &sdkws.GroupMemberFullInfo{ -// GroupID: member.GroupID, -// UserID: member.UserID, -// RoleLevel: member.RoleLevel, -// JoinTime: member.JoinTime, -// Nickname: member.Nickname, -// FaceURL: member.FaceURL, -// AppMangerLevel: 0, -// JoinSource: member.JoinSource, -// OperatorUserID: member.OperatorUserID, -// Ex: member.Ex, -// MuteEndTime: member.MuteEndTime, -// InviterUserID: member.InviterUserID, -// } -// } -// res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) -// for _, userID := range userIDs { -// res = append(res, memberMap[userID]) -// } -// val, _ := json.Marshal(res) -// sum := md5.Sum(val) -// return binary.BigEndian.Uint64(sum[:]) -//} +func (g *Group) getGroupHash(members []*model_struct.LocalGroupMember) uint64 { + userIDs := datautil.Slice(members, func(member *model_struct.LocalGroupMember) string { + return member.UserID + }) + datautil.Sort(userIDs, true) + memberMap := make(map[string]*sdkws.GroupMemberFullInfo) + for _, member := range members { + memberMap[member.UserID] = &sdkws.GroupMemberFullInfo{ + GroupID: member.GroupID, + UserID: member.UserID, + RoleLevel: member.RoleLevel, + JoinTime: member.JoinTime, + Nickname: member.Nickname, + FaceURL: member.FaceURL, + AppMangerLevel: 0, + JoinSource: member.JoinSource, + OperatorUserID: member.OperatorUserID, + Ex: member.Ex, + MuteEndTime: member.MuteEndTime, + InviterUserID: member.InviterUserID, + } + } + res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) + for _, userID := range userIDs { + res = append(res, memberMap[userID]) + } + val, _ := json.Marshal(res) + sum := md5.Sum(val) + return binary.BigEndian.Uint64(sum[:]) +} func (g *Group) SyncAllGroupMember(ctx context.Context, groupID string) error { + absInfo, err := g.GetGroupAbstractInfo(ctx, groupID) + if err != nil { + return err + } + localData, err := g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) + if err != nil { + return err + } + hashCode := g.getGroupHash(localData) + if len(localData) == int(absInfo.GroupMemberNumber) && hashCode == absInfo.GroupMemberListHash { + log.ZDebug(ctx, "SyncAllGroupMember no change in personnel", "groupID", groupID, "hashCode", hashCode, "absInfo.GroupMemberListHash", absInfo.GroupMemberListHash) + return nil + } + members, err := g.GetServerGroupMembers(ctx, groupID) + if err != nil { + return err + } + return g.syncGroupMembers(ctx, groupID, members, localData) +} + +func (g *Group) SyncAllGroupMember2(ctx context.Context, groupID string) error { return g.IncrSyncGroupMember(ctx, groupID) - //absInfo, err := g.GetGroupAbstractInfo(ctx, groupID) - //if err != nil { - // return err - //} - //localData, err := g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) - //if err != nil { - // return err - //} - //hashCode := g.getGroupHash(localData) - //if len(localData) == int(absInfo.GroupMemberNumber) && hashCode == absInfo.GroupMemberListHash { - // log.ZDebug(ctx, "SyncAllGroupMember no change in personnel", "groupID", groupID, "hashCode", hashCode, "absInfo.GroupMemberListHash", absInfo.GroupMemberListHash) - // return nil - //} - //members, err := g.GetServerGroupMembers(ctx, groupID) - //if err != nil { - // return err - //} - //return g.syncGroupMembers(ctx, groupID, members, localData) } func (g *Group) syncGroupMembers(ctx context.Context, groupID string, members []*sdkws.GroupMemberFullInfo, localData []*model_struct.LocalGroupMember) error { @@ -165,46 +174,62 @@ func (g *Group) deleteGroup(ctx context.Context, groupID string) error { } func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { + t := time.Now() + defer func(start time.Time) { + + elapsed := time.Since(start).Milliseconds() + log.ZDebug(ctx, "SyncAllJoinedGroupsAndMembers fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) + + }(t) + _, err := g.syncAllJoinedGroups(ctx) + if err != nil { + return err + } + groups, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + var wg sync.WaitGroup + for _, group := range groups { + wg.Add(1) + go func(groupID string) { + defer wg.Done() + if err := g.SyncAllGroupMember(ctx, groupID); err != nil { + log.ZError(ctx, "SyncGroupMember failed", err) + } + }(group.GroupID) + } + wg.Wait() + return nil +} +func (g *Group) SyncAllJoinedGroupsAndMembers2(ctx context.Context) error { + t := time.Now() + defer func(start time.Time) { + + elapsed := time.Since(start).Milliseconds() + log.ZDebug(ctx, "SyncAllJoinedGroupsAndMembers fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) + + }(t) if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } return g.IncrSyncJoinGroupMember(ctx) - //_, err := g.syncAllJoinedGroups(ctx) - //if err != nil { - // return err - //} - //groups, err := g.db.GetJoinedGroupListDB(ctx) - //if err != nil { - // return err - //} - //var wg sync.WaitGroup - //for _, group := range groups { - // wg.Add(1) - // go func(groupID string) { - // defer wg.Done() - // if err := g.SyncAllGroupMember(ctx, groupID); err != nil { - // log.ZError(ctx, "SyncGroupMember failed", err) - // } - // }(group.GroupID) - //} - //wg.Wait() - //return nil } -//func (g *Group) syncAllJoinedGroups(ctx context.Context) ([]*sdkws.GroupInfo, error) { -// groups, err := g.GetServerJoinGroup(ctx) -// if err != nil { -// return nil, err -// } -// localData, err := g.db.GetJoinedGroupListDB(ctx) -// if err != nil { -// return nil, err -// } -// if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { -// return nil, err -// } -// return groups, nil -//} +func (g *Group) syncAllJoinedGroups(ctx context.Context) ([]*sdkws.GroupInfo, error) { + groups, err := g.GetServerJoinGroup(ctx) + if err != nil { + return nil, err + } + localData, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return nil, err + } + if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { + return nil, err + } + return groups, nil +} func (g *Group) SyncAllSelfGroupApplication(ctx context.Context) error { list, err := g.GetServerSelfGroupApplication(ctx) diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 07a6cd893..3151e55ef 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -8,18 +8,22 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" pconstant "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/group" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" + "sync" ) +type BatchIncrementalReq struct { + UserID string `json:"user_id"` + List []*group.GetIncrementalGroupMemberReq `json:"list"` +} +type BatchIncrementalResp struct { + List map[string]*group.GetIncrementalGroupMemberResp `json:"list"` +} + func (g *Group) getIncrementalGroupMemberBatch(ctx context.Context, groups []*group.GetIncrementalGroupMemberReq) (map[string]*group.GetIncrementalGroupMemberResp, error) { - type BatchIncrementalReq struct { - UserID string `json:"user_id"` - List []*group.GetIncrementalGroupMemberReq `json:"list"` - } - type BatchIncrementalResp struct { - List map[string]*group.GetIncrementalGroupMemberResp `json:"list"` - } resp, err := util.CallApi[BatchIncrementalResp](ctx, constant.GetIncrementalGroupMemberBatch, &BatchIncrementalReq{UserID: g.loginUserID, List: groups}) if err != nil { return nil, err @@ -27,8 +31,12 @@ func (g *Group) getIncrementalGroupMemberBatch(ctx context.Context, groups []*gr return resp.List, nil } -func (g *Group) groupMemberVersionKey(groupID string) string { - return "friend:" + groupID +func (g *Group) groupMemberTableName() string { + return model_struct.LocalGroupMember{}.TableName() +} + +func (g *Group) groupTableName() string { + return model_struct.LocalGroup{}.TableName() } func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { @@ -43,6 +51,7 @@ func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { } func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) error { + var wg sync.WaitGroup if len(groupIDs) == 0 { return nil } @@ -65,7 +74,7 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err req := group.GetIncrementalGroupMemberReq{ GroupID: groupID, } - lvs, err := g.db.GetVersionSync(ctx, g.groupMemberVersionKey(groupID)) + lvs, err := g.db.GetVersionSync(ctx, g.groupMemberTableName(), groupID) if err == nil { req.VersionID = lvs.VersionID req.Version = lvs.Version @@ -80,28 +89,35 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err } groups = groups[:0] for groupID, resp := range groupVersion { - if err := g.syncGroupMember(ctx, groupID, resp); err != nil { - return err - } - delete(groupIDSet, groupID) + tempResp := resp + tempGroupID := groupID + wg.Add(1) + go func() error { + if err := g.syncGroupMember(ctx, tempGroupID, tempResp); err != nil { + return err + } + wg.Done() + return nil + }() + delete(groupIDSet, tempGroupID) } + wg.Wait() num := len(groupIDSet) _ = num } } func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group.GetIncrementalGroupMemberResp) error { - opt := incrversion.Option[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ - Ctx: ctx, - DB: g.db, - Key: func(localFriend *model_struct.LocalGroupMember) string { - return localFriend.UserID - }, - SyncKey: func() string { - return g.groupMemberVersionKey(groupID) + groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ + Ctx: ctx, + DB: g.db, + TabName: g.groupMemberTableName(), + EntityID: groupID, + Key: func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID }, Local: func() ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupMemberListSplit(ctx, groupID, 0, 0, 9999999) + return g.db.GetGroupMemberListByGroupID(ctx, groupID) }, ServerVersion: func() *group.GetIncrementalGroupMemberResp { return resp @@ -112,31 +128,120 @@ func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group Version: func(resp *group.GetIncrementalGroupMemberResp) (string, uint64) { return resp.VersionID, resp.Version }, - DeleteIDs: func(resp *group.GetIncrementalGroupMemberResp) []string { - return resp.DeleteUserIds + Delete: func(resp *group.GetIncrementalGroupMemberResp) []string { + return resp.Delete }, - Changes: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { - return util.Batch(ServerGroupMemberToLocalGroupMember, resp.Changes) + Update: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { + return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Update) + }, + Insert: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { + return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Insert) }, Syncer: func(server, local []*model_struct.LocalGroupMember) error { return g.groupMemberSyncer.Sync(ctx, server, local, nil) }, + FullSyncer: func(ctx context.Context) error { + return g.groupMemberSyncer.FullSync(ctx, groupID) + }, + FullID: func(ctx context.Context) ([]string, error) { + resp, err := util.CallApi[group.GetIncrementalGroupMemberUserIDsResp](ctx, constant.GetGroupMemberAllIDs, &group.GetIncrementalGroupMemberUserIDsReq{ + GroupID: groupID, + }) + if err != nil { + return nil, err + } + return resp.UserIDs, nil + }, } - return opt.Sync() + return groupMemberSyncer.Sync() } -func (g *Group) groupJoinVersionKey() string { - return "join_group:" + g.loginUserID +func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delete, update, insert []*sdkws.GroupMemberFullInfo, version uint64) error { + groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ + Ctx: ctx, + DB: g.db, + TabName: g.groupMemberTableName(), + EntityID: groupID, + Key: func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + Local: func() ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListByGroupID(ctx, groupID) + }, + ServerVersion: func() *group.GetIncrementalGroupMemberResp { + return &group.GetIncrementalGroupMemberResp{ + Version: version, + VersionID: "", + Full: false, + Delete: datautil.Slice(delete, func(e *sdkws.GroupMemberFullInfo) string { + return e.UserID + }), + Insert: insert, + Update: update, + } + }, + Server: func(version *model_struct.LocalVersionSync) (*group.GetIncrementalGroupMemberResp, error) { + singleGroupReq := &group.GetIncrementalGroupMemberReq{ + GroupID: groupID, + VersionID: version.VersionID, + Version: version.Version, + } + resp, err := util.CallApi[BatchIncrementalResp](ctx, constant.GetIncrementalGroupMemberBatch, + &BatchIncrementalReq{UserID: g.loginUserID, List: []*group.GetIncrementalGroupMemberReq{singleGroupReq}}) + if err != nil { + return nil, err + } + if resp.List != nil { + if singleGroupResp, ok := resp.List[groupID]; ok { + return singleGroupResp, nil + } + } + return nil, errs.New("group member version record not found") + + }, + Full: func(resp *group.GetIncrementalGroupMemberResp) bool { + return resp.Full + }, + Version: func(resp *group.GetIncrementalGroupMemberResp) (string, uint64) { + return resp.VersionID, resp.Version + }, + Delete: func(resp *group.GetIncrementalGroupMemberResp) []string { + return resp.Delete + }, + Update: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { + return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Update) + }, + Insert: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { + return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Insert) + }, + Syncer: func(server, local []*model_struct.LocalGroupMember) error { + return g.groupMemberSyncer.Sync(ctx, server, local, nil) + }, + FullSyncer: func(ctx context.Context) error { + return g.groupMemberSyncer.FullSync(ctx, groupID) + }, + FullID: func(ctx context.Context) ([]string, error) { + resp, err := util.CallApi[group.GetIncrementalGroupMemberUserIDsResp](ctx, constant.GetGroupMemberAllIDs, &group.GetIncrementalGroupMemberUserIDsReq{ + GroupID: groupID, + }) + if err != nil { + return nil, err + } + return resp.UserIDs, nil + }, + } + return groupMemberSyncer.CheckVersionSync() } func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { - opt := incrversion.Option[*model_struct.LocalGroup, *group.GetIncrementalJoinGroupResp]{ - Ctx: ctx, - DB: g.db, - Key: func(localFriend *model_struct.LocalGroup) string { - return localFriend.GroupID + opt := incrversion.VersionSynchronizer[*model_struct.LocalGroup, *group.GetIncrementalJoinGroupResp]{ + Ctx: ctx, + DB: g.db, + TabName: g.groupTableName(), + EntityID: g.loginUserID, + Key: func(LocalGroup *model_struct.LocalGroup) string { + return LocalGroup.GroupID }, - SyncKey: g.groupJoinVersionKey, Local: func() ([]*model_struct.LocalGroup, error) { return g.db.GetJoinedGroupListDB(ctx) }, @@ -153,15 +258,31 @@ func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { Version: func(resp *group.GetIncrementalJoinGroupResp) (string, uint64) { return resp.VersionID, resp.Version }, - DeleteIDs: func(resp *group.GetIncrementalJoinGroupResp) []string { - return resp.DeleteGroupIds + Delete: func(resp *group.GetIncrementalJoinGroupResp) []string { + return resp.Delete }, - Changes: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { - return util.Batch(ServerGroupToLocalGroup, resp.Changes) + Update: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { + return util.Batch(ServerGroupToLocalGroup, resp.Update) + }, + Insert: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { + return datautil.Batch(ServerGroupToLocalGroup, resp.Insert) }, Syncer: func(server, local []*model_struct.LocalGroup) error { return g.groupSyncer.Sync(ctx, server, local, nil) }, + FullSyncer: func(ctx context.Context) error { + return g.groupSyncer.FullSync(ctx, g.loginUserID) + }, + FullID: func(ctx context.Context) ([]string, error) { + resp, err := util.CallApi[group.GetIncrementalJoinGroupIDsResp](ctx, constant.GetJoinedGroupAllIDs, &group.GetIncrementalJoinGroupIDsReq{ + UserID: g.loginUserID, + }) + if err != nil { + return nil, err + } + return resp.GroupIDs, nil + + }, } return opt.Sync() } diff --git a/internal/group/sync2_test.go b/internal/group/sync2_test.go new file mode 100644 index 000000000..654521e1a --- /dev/null +++ b/internal/group/sync2_test.go @@ -0,0 +1 @@ +package group diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index c4e20ca83..38771d36e 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -4,85 +4,215 @@ import ( "context" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" - "time" + "gorm.io/gorm" + "sort" ) -type Option[V, R any] struct { +type VersionSynchronizer[V, R any] struct { Ctx context.Context DB db_interface.VersionSyncModel + TabName string + EntityID string Key func(V) string - SyncKey func() string Local func() ([]V, error) ServerVersion func() R Server func(version *model_struct.LocalVersionSync) (R, error) Full func(resp R) bool Version func(resp R) (string, uint64) - DeleteIDs func(resp R) []string - Changes func(resp R) []V + Delete func(resp R) []string + Update func(resp R) []V + Insert func(resp R) []V Syncer func(server, local []V) error + FullSyncer func(ctx context.Context) error + FullID func(ctx context.Context) ([]string, error) } -func (o *Option[V, R]) getVersionInfo() *model_struct.LocalVersionSync { - key := o.SyncKey() - versionInfo, err := o.DB.GetVersionSync(o.Ctx, key) - if err != nil { - log.ZInfo(o.Ctx, "get version info", "error", err) - return &model_struct.LocalVersionSync{ - Key: key, - } +func (o *VersionSynchronizer[V, R]) getVersionInfo() (*model_struct.LocalVersionSync, error) { + versionInfo, err := o.DB.GetVersionSync(o.Ctx, o.TabName, o.EntityID) + if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound { + log.ZWarn(o.Ctx, "get version info", err) + return nil, err + } - return versionInfo + return versionInfo, nil +} + +func (o *VersionSynchronizer[V, R]) updateVersionInfo(lvs *model_struct.LocalVersionSync, resp R) error { + lvs.Table = o.TabName + lvs.EntityID = o.EntityID + lvs.VersionID, lvs.Version = o.Version(resp) + return o.DB.SetVersionSync(o.Ctx, lvs) } -func (o *Option[V, R]) Sync() error { +func (o *VersionSynchronizer[V, R]) Sync() error { + var lvs *model_struct.LocalVersionSync var resp R if o.ServerVersion == nil { - version := o.getVersionInfo() var err error - resp, err = o.Server(version) + lvs, err = o.getVersionInfo() + if err != nil { + return err + } + resp, err = o.Server(lvs) if err != nil { return err } } else { + var err error + lvs, err = o.getVersionInfo() + if err != nil { + return err + } resp = o.ServerVersion() } - delIDs := o.DeleteIDs(resp) - changes := o.Changes(resp) - updateVersionInfo := func() error { - lvs := &model_struct.LocalVersionSync{ - Key: o.SyncKey(), - CreateTime: time.Now().UnixMilli(), - } - lvs.VersionID, lvs.Version = o.Version(resp) - return o.DB.SetVersionSync(o.Ctx, lvs) + delIDs := o.Delete(resp) + changes := o.Update(resp) + insert := o.Insert(resp) + + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { + log.ZDebug(o.Ctx, "no data to sync", "table", o.TabName, "entityID", o.EntityID) + return nil } - if len(delIDs)+len(changes) == 0 { - return updateVersionInfo() + + if o.Full(resp) { + err := o.FullSyncer(o.Ctx) + if err != nil { + return err + } + lvs.UIDList, err = o.FullID(o.Ctx) + if err != nil { + return err + } + } else { + if len(delIDs) > 0 { + lvs.UIDList = DeleteElements(lvs.UIDList, delIDs) + } + if len(insert) > 0 { + lvs.UIDList = append(lvs.UIDList, datautil.Slice(insert, o.Key)...) + + } + local, err := o.Local() + if err != nil { + return err + } + kv := datautil.SliceToMapAny(local, func(v V) (string, V) { + return o.Key(v), v + }) + for i, change := range append(changes, insert...) { + key := o.Key(change) + kv[key] = changes[i] + } + + for _, id := range delIDs { + delete(kv, id) + } + server := datautil.Values(kv) + if err := o.Syncer(server, local); err != nil { + return err + } } - local, err := o.Local() + return o.updateVersionInfo(lvs, resp) +} + +func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { + lvs, err := o.getVersionInfo() if err != nil { return err } - var server []V - if o.Full(resp) { - server = changes - } else { + resp := o.ServerVersion() + delIDs := o.Delete(resp) + changes := o.Update(resp) + insert := o.Insert(resp) + _, version := o.Version(resp) + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { + log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TabName, "entityID", o.EntityID) + return nil + } + if lvs.Version+1 == version { + if len(delIDs) > 0 { + lvs.UIDList = DeleteElements(lvs.UIDList, delIDs) + } + if len(insert) > 0 { + lvs.UIDList = append(lvs.UIDList, datautil.Slice(insert, o.Key)...) + + } + local, err := o.Local() + if err != nil { + return err + } kv := datautil.SliceToMapAny(local, func(v V) (string, V) { return o.Key(v), v }) - for i, change := range changes { + for i, change := range append(changes, insert...) { key := o.Key(change) kv[key] = changes[i] } + for _, id := range delIDs { delete(kv, id) } - server = datautil.Values(kv) + server := datautil.Values(kv) + if err := o.Syncer(server, local); err != nil { + return err + } + return o.updateVersionInfo(lvs, resp) + } else if version <= lvs.Version { + log.ZWarn(o.Ctx, "version less than local version", errs.New("version less than local version"), + "table", o.TabName, "entityID", o.EntityID, "version", version, "localVersion", lvs.Version) + return nil + } else { + // Re-fetch the version number from the server, compare it with the local version number, and fetch the difference once. + o.ServerVersion = nil + return o.Sync() } - if err := o.Syncer(server, local); err != nil { - return err +} + +// DeleteElements 删除切片中包含在另一个切片中的元素,并保持切片顺序 +func DeleteElements[E comparable](es []E, toDelete []E) []E { + // 将要删除的元素存储在哈希集合中 + deleteSet := make(map[E]struct{}, len(toDelete)) + for _, e := range toDelete { + deleteSet[e] = struct{}{} } - return updateVersionInfo() + + // 通过一个索引 j 来跟踪新的切片位置 + j := 0 + for _, e := range es { + if _, found := deleteSet[e]; !found { + es[j] = e + j++ + } + } + return es[:j] +} + +// DeleteElement 删除切片中的指定元素,并保持切片顺序 +func DeleteElement[E comparable](es []E, element E) []E { + j := 0 + for _, e := range es { + if e != element { + es[j] = e + j++ + } + } + return es[:j] +} + +// Slice Converts slice types in batches and sorts the resulting slice using a custom comparator +func Slice[E any, T any](es []E, fn func(e E) T, less func(a, b T) bool) []T { + // 转换切片 + v := make([]T, len(es)) + for i := 0; i < len(es); i++ { + v[i] = fn(es[i]) + } + + // 排序切片 + sort.Slice(v, func(i, j int) bool { + return less(v[i], v[j]) + }) + + return v } diff --git a/internal/user/user.go b/internal/user/user.go index 0588a6dee..40597513a 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -45,8 +45,8 @@ type User struct { db_interface.DataBase loginUserID string listener func() open_im_sdk_callback.OnUserListener - userSyncer *syncer.Syncer[*model_struct.LocalUser, string] - commandSyncer *syncer.Syncer[*model_struct.LocalUserCommand, string] + userSyncer *syncer.Syncer[*model_struct.LocalUser, syncer.NoResp, string] + commandSyncer *syncer.Syncer[*model_struct.LocalUserCommand, syncer.NoResp, string] conversationCh chan common.Cmd2Value UserBasicCache *cache.Cache[string, *BasicInfo] OnlineStatusCache *cache.Cache[string, *userPb.OnlineStatus] @@ -67,7 +67,7 @@ func NewUser(dataBase db_interface.DataBase, loginUserID string, conversationCh } func (u *User) initSyncer() { - u.userSyncer = syncer.New( + u.userSyncer = syncer.New[*model_struct.LocalUser, syncer.NoResp, string]( func(ctx context.Context, value *model_struct.LocalUser) error { return u.InsertLoginUser(ctx, value) }, @@ -93,7 +93,7 @@ func (u *User) initSyncer() { return nil }, ) - u.commandSyncer = syncer.New( + u.commandSyncer = syncer.New[*model_struct.LocalUserCommand, syncer.NoResp, string]( func(ctx context.Context, command *model_struct.LocalUserCommand) error { // Logic to insert a command return u.DataBase.ProcessUserCommandAdd(ctx, command) diff --git a/internal/util/notice.go b/internal/util/notice.go index 085a4b9c7..06ec7f187 100644 --- a/internal/util/notice.go +++ b/internal/util/notice.go @@ -14,21 +14,15 @@ package util -import ( - "context" - "encoding/json" - "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" -) - -func NoticeChange[T any](fn func(data string)) func(ctx context.Context, state int, value T) error { - return func(ctx context.Context, state int, value T) error { - if state != syncer.Unchanged { - data, err := json.Marshal(value) - if err != nil { - return err - } - fn(string(data)) - } - return nil - } -} +//func NoticeChange[T any](fn func(data string)) func(ctx context.Context, state int, value T) error { +// return func(ctx context.Context, state int, value T) error { +// if state != syncer.Unchanged { +// data, err := json.Marshal(value) +// if err != nil { +// return err +// } +// fn(string(data)) +// } +// return nil +// } +//} diff --git a/internal/util/post.go b/internal/util/post.go index 17a0004e1..a5c27ceea 100644 --- a/internal/util/post.go +++ b/internal/util/post.go @@ -20,7 +20,9 @@ import ( "encoding/json" "fmt" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" + "github.com/openimsdk/openim-sdk-core/v3/pkg/page" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" + "github.com/openimsdk/tools/errs" "io" "net/http" "time" @@ -174,3 +176,64 @@ func GetPageAll[A interface { } return res, nil } + +func GetPageAllWithMaxNum[A interface { + GetPagination() *sdkws.RequestPagination +}, B, C any](ctx context.Context, api string, req A, fn func(resp *B) []C, maxItems int) ([]C, error) { + if req.GetPagination().ShowNumber <= 0 { + req.GetPagination().ShowNumber = 50 + } + var res []C + totalFetched := 0 + for i := int32(0); ; i++ { + req.GetPagination().PageNumber = i + 1 + memberResp, err := CallApi[B](ctx, api, req) + if err != nil { + return nil, err + } + list := fn(memberResp) + res = append(res, list...) + totalFetched += len(list) + if len(list) < int(req.GetPagination().ShowNumber) || (maxItems > 0 && totalFetched >= maxItems) { + break + } + } + if maxItems > 0 && len(res) > maxItems { + res = res[:maxItems] + } + return res, nil +} + +func FetchAndInsertPagedData[RESP, L any](ctx context.Context, api string, req page.PageReq, fn func(resp *RESP) []L, batchInsertFn func(ctx context.Context, items []L) error, + insertFn func(ctx context.Context, item L) error, maxItems int) error { + if req.GetPagination().ShowNumber <= 0 { + req.GetPagination().ShowNumber = 50 + } + var errSingle error + errSingle = nil + totalFetched := 0 + for i := int32(0); ; i++ { + req.GetPagination().PageNumber = i + 1 + memberResp, err := CallApi[RESP](ctx, api, req) + if err != nil { + return err + } + list := fn(memberResp) + if err := batchInsertFn(ctx, list); err != nil { + for _, item := range list { + errSingle = insertFn(ctx, item) + if errSingle != nil { + errSingle = errs.New(errSingle.Error(), "item", item) + } + } + } + totalFetched += len(list) + if len(list) < int(req.GetPagination().ShowNumber) || (maxItems > 0 && totalFetched >= maxItems) { + break + } + } + if errSingle != nil { + return errs.WrapMsg(errSingle, "batch insert failed due to data exception") + } + return nil +} diff --git a/pkg/constant/server_api_router.go b/pkg/constant/server_api_router.go index 1b1c602fd..1462b779b 100644 --- a/pkg/constant/server_api_router.go +++ b/pkg/constant/server_api_router.go @@ -107,6 +107,8 @@ const ( //SearchGroupMember = RouterGroup + "/search_group_member" GetIncrementalJoinGroup = RouterGroup + "/get_incremental_join_group" GetIncrementalGroupMemberBatch = RouterGroup + "/get_incremental_group_member_batch" + GetJoinedGroupAllIDs = RouterGroup + "/get_incremental_join_group_ids" + GetGroupMemberAllIDs = RouterGroup + "/get_incremental_group_member_user_ids" SetReceiveMessageOptRouter = "/conversation/set_receive_message_opt" GetReceiveMessageOptRouter = "/conversation/get_receive_message_opt" diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index a497b9934..68e8669fa 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -24,6 +24,8 @@ type GroupModel interface { InsertGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error DeleteGroup(ctx context.Context, groupID string) error UpdateGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error + BatchInsertGroup(ctx context.Context, groupList []*model_struct.LocalGroup) error + DeleteAllGroup(ctx context.Context) error GetJoinedGroupListDB(ctx context.Context) ([]*model_struct.LocalGroup, error) GetGroups(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) GetGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error) @@ -226,6 +228,7 @@ type UserModel interface { type FriendModel interface { InsertFriend(ctx context.Context, friend *model_struct.LocalFriend) error DeleteFriendDB(ctx context.Context, friendUserID string) error + GetFriendListCount(ctx context.Context) (int64, error) UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error) GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error) @@ -274,7 +277,7 @@ type SendingMessagesModel interface { } type VersionSyncModel interface { - GetVersionSync(ctx context.Context, key string) (*model_struct.LocalVersionSync, error) + GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error) SetVersionSync(ctx context.Context, version *model_struct.LocalVersionSync) error } diff --git a/pkg/db/friend_model.go b/pkg/db/friend_model.go index d55b2298c..ba2030f8f 100644 --- a/pkg/db/friend_model.go +++ b/pkg/db/friend_model.go @@ -37,6 +37,14 @@ func (d *DataBase) DeleteFriendDB(ctx context.Context, friendUserID string) erro return utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id=? and friend_user_id=?", d.loginUserID, friendUserID).Delete(&model_struct.LocalFriend{}).Error, "DeleteFriend failed") } +func (d *DataBase) GetFriendListCount(ctx context.Context) (int64, error) { + d.friendMtx.Lock() + defer d.friendMtx.Unlock() + var count int64 + err := d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Count(&count).Error + return count, utils.Wrap(err, "GetFriendListCount failed") +} + func (d *DataBase) UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() diff --git a/pkg/db/group_model.go b/pkg/db/group_model.go index bc2fe6651..42ab308fe 100644 --- a/pkg/db/group_model.go +++ b/pkg/db/group_model.go @@ -23,6 +23,7 @@ import ( "fmt" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" ) @@ -49,6 +50,18 @@ func (d *DataBase) UpdateGroup(ctx context.Context, groupInfo *model_struct.Loca return utils.Wrap(t.Error, "") } +func (d *DataBase) BatchInsertGroup(ctx context.Context, groupList []*model_struct.LocalGroup) error { + d.groupMtx.Lock() + defer d.groupMtx.Unlock() + return utils.Wrap(d.conn.WithContext(ctx).Create(groupList).Error, "BatchInsertGroup failed") +} + +func (d *DataBase) DeleteAllGroup(ctx context.Context) error { + d.groupMtx.Lock() + defer d.groupMtx.Unlock() + return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&model_struct.LocalGroup{}).Error, "DeleteAllGroup failed") +} + func (d *DataBase) GetJoinedGroupListDB(ctx context.Context) ([]*model_struct.LocalGroup, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 7e59839e9..3cd9771f8 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -14,6 +14,12 @@ package model_struct +import ( + "database/sql/driver" + "encoding/json" + "github.com/openimsdk/tools/errs" +) + // //message FriendInfo{ //string OwnerUserID = 1; @@ -139,6 +145,10 @@ type LocalGroup struct { NotificationUserID string `gorm:"column:notification_user_id;size:64" json:"notificationUserID"` } +func (LocalGroup) TableName() string { + return "local_groups" +} + //message GroupMemberFullInfo { //string GroupID = 1 ; //string UserID = 2 ; @@ -175,6 +185,10 @@ type LocalGroupMember struct { AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` } +func (LocalGroupMember) TableName() string { + return "local_group_members" +} + // message GroupRequest{ // string UserID = 1; // string GroupID = 2; @@ -532,11 +546,27 @@ func (LocalUserCommand) TableName() string { return "local_user_command" } +type StringArray []string + +func (a StringArray) Value() (driver.Value, error) { + return json.Marshal(a) +} + +func (a *StringArray) Scan(value interface{}) error { + b, ok := value.([]byte) + if !ok { + return errs.New("type assertion to []byte failed").Wrap() + } + return json.Unmarshal(b, &a) +} + type LocalVersionSync struct { - Key string `gorm:"column:key;type:varchar(255);primary_key" json:"key"` - VersionID string `gorm:"column:version_id" json:"versionID"` - Version uint64 `gorm:"column:version" json:"version"` - CreateTime int64 `gorm:"column:create_time" json:"createTime"` + Table string `gorm:"column:table;type:varchar(255);primary_key" json:"table"` + EntityID string `gorm:"column:entity_id;type:varchar(255);primary_key" json:"entityID"` + VersionID string `gorm:"column:version_id" json:"versionID"` + Version uint64 `gorm:"column:version" json:"version"` + CreateTime int64 `gorm:"column:create_time" json:"createTime"` + UIDList StringArray `gorm:"column:id_list;type:text" json:"uidList"` } func (LocalVersionSync) TableName() string { diff --git a/pkg/db/version_sync.go b/pkg/db/version_sync.go index 34cb19d9f..ade89aa24 100644 --- a/pkg/db/version_sync.go +++ b/pkg/db/version_sync.go @@ -4,29 +4,36 @@ import ( "context" "errors" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" ) -func (d *DataBase) GetVersionSync(ctx context.Context, key string) (*model_struct.LocalVersionSync, error) { +func (d *DataBase) GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error) { d.versionMtx.RLock() defer d.versionMtx.RUnlock() var res model_struct.LocalVersionSync - return &res, utils.Wrap(d.conn.WithContext(ctx).Where("`key` = ? ", key).Take(&res).Error, "GetVersionSync failed") + return &res, errs.Wrap(d.conn.WithContext(ctx).Where("`table` = ? and `entity_id` = ?", tableName, entityID).Take(&res).Error) } func (d *DataBase) SetVersionSync(ctx context.Context, lv *model_struct.LocalVersionSync) error { d.versionMtx.Lock() defer d.versionMtx.Unlock() - res := d.conn.WithContext(ctx).Where("`key` = ?", lv.Key).Save(lv) - if res.Error != nil { - return utils.Wrap(res.Error, "SetVersionSync failed") - } - if res.RowsAffected > 0 { + + var existing model_struct.LocalVersionSync + err := d.conn.WithContext(ctx).Where("`table` = ? AND `entity_id` = ?", lv.Table, lv.EntityID).First(&existing).Error + + if errors.Is(err, gorm.ErrRecordNotFound) { + if createErr := d.conn.WithContext(ctx).Create(lv).Error; createErr != nil { + return errs.Wrap(createErr) + } return nil + } else if err != nil { + return errs.Wrap(err) } - if err := d.conn.WithContext(ctx).Create(lv).Error; err != nil && !errors.Is(err, gorm.ErrDuplicatedKey) { - return utils.Wrap(err, "SetVersionSync failed") + + if updateErr := d.conn.WithContext(ctx).Model(&existing).Updates(lv).Error; updateErr != nil { + return errs.Wrap(updateErr) } + return nil } diff --git a/pkg/page/pagereq.go b/pkg/page/pagereq.go new file mode 100644 index 000000000..b8887ab92 --- /dev/null +++ b/pkg/page/pagereq.go @@ -0,0 +1,7 @@ +package page + +import "github.com/openimsdk/protocol/sdkws" + +type PageReq interface { + GetPagination() *sdkws.RequestPagination +} diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index 38aeab161..d4c5acdae 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -16,9 +16,11 @@ package syncer import ( "context" - "reflect" - "github.com/google/go-cmp/cmp" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" + "github.com/openimsdk/openim-sdk-core/v3/pkg/page" + "github.com/openimsdk/tools/errs" + "reflect" "github.com/openimsdk/tools/log" ) @@ -32,14 +34,14 @@ import ( // - equal: A function to check if two data items are equal. // - notice: A function to handle notifications during the sync process. // Panics if insert, delete, update, or uuid functions are not provided. -func New[T any, V comparable]( +func New[T, RESP any, V comparable]( insert func(ctx context.Context, value T) error, delete func(ctx context.Context, value T) error, update func(ctx context.Context, server T, local T) error, uuid func(value T) V, equal func(a T, b T) bool, notice func(ctx context.Context, state int, server, local T) error, -) *Syncer[T, V] { +) *Syncer[T, RESP, V] { if insert == nil || update == nil || delete == nil || uuid == nil { panic("invalid params") } @@ -52,7 +54,7 @@ func New[T any, V comparable]( } // Return a new Syncer instance with the provided functions and the type as a string. - return &Syncer[T, V]{ + return &Syncer[T, RESP, V]{ insert: insert, update: update, delete: delete, @@ -66,19 +68,143 @@ func New[T any, V comparable]( // Syncer is a struct that holds functions for synchronizing data. // It includes functions for inserting, updating, deleting, and notifying, // as well as functions for generating unique IDs and checking equality of data items. -type Syncer[T any, V comparable] struct { - insert func(ctx context.Context, server T) error - update func(ctx context.Context, server T, local T) error - delete func(ctx context.Context, local T) error - notice func(ctx context.Context, state int, server, local T) error - equal func(server T, local T) bool - uuid func(value T) V - ts string // Represents the type of T as a string. +type Syncer[T, RESP any, V comparable] struct { + insert func(ctx context.Context, server T) error + update func(ctx context.Context, server T, local T) error + delete func(ctx context.Context, local T) error + batchInsert func(ctx context.Context, servers []T) error + deleteAll func(ctx context.Context, entityID string) error + notice func(ctx context.Context, state int, server, local T) error + equal func(server T, local T) bool + uuid func(value T) V + batchPageReq func(entityID string) page.PageReq + batchPageRespConvertFunc func(resp *RESP) []T + reqApiRouter string + ts string // Represents the type of T as a string. + +} + +type NoResp struct{} + +func New2[T, RESP any, V comparable](opts ...Option[T, RESP, V]) *Syncer[T, RESP, V] { + // Create a new Syncer instance. + s := &Syncer[T, RESP, V]{} + + // Apply the options to the Syncer. + for _, opt := range opts { + opt(s) + } + + // Check required functions. + if s.insert == nil || s.update == nil || s.delete == nil || s.uuid == nil { + panic("invalid params") + } + + // Determine the type of T and remove pointer indirection if necessary. + var t T + tof := reflect.TypeOf(&t) + for tof.Kind() == reflect.Ptr { + tof = tof.Elem() + } + + // Set the type string. + s.ts = tof.String() + + return s +} + +// Option is a function that configures a Syncer. +type Option[T, RESP any, V comparable] func(*Syncer[T, RESP, V]) + +// WithInsert sets the insert function for the Syncer. +func WithInsert[T, RESP any, V comparable](f func(ctx context.Context, value T) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.insert = f + } +} + +// WithUpdate sets the update function for the Syncer. +func WithUpdate[T, RESP any, V comparable](f func(ctx context.Context, server T, local T) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.update = f + } +} + +// WithDelete sets the delete function for the Syncer. +func WithDelete[T, RESP any, V comparable](f func(ctx context.Context, local T) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.delete = f + } +} + +// WithBatchInsert sets the batchInsert function for the Syncer. +func WithBatchInsert[T, RESP any, V comparable](f func(ctx context.Context, values []T) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.batchInsert = f + } +} + +// WithDeleteAll sets the deleteAll function for the Syncer. +func WithDeleteAll[T, RESP any, V comparable](f func(ctx context.Context, entityID string) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.deleteAll = f + } +} + +// WithUUID sets the uuid function for the Syncer. +func WithUUID[T, RESP any, V comparable](f func(value T) V) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.uuid = f + } +} + +// WithEqual sets the equal function for the Syncer. +func WithEqual[T, RESP any, V comparable](f func(a T, b T) bool) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.equal = f + } +} + +// WithNotice sets the notice function for the Syncer. +func WithNotice[T, RESP any, V comparable](f func(ctx context.Context, state int, server, local T) error) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.notice = f + } +} + +// WithBatchPageReq sets the batchPageReq for the Syncer. +func WithBatchPageReq[T, RESP any, V comparable](f func(entityID string) page.PageReq) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.batchPageReq = f + } +} + +// WithBatchPageRespConvertFunc sets the batchPageRespConvertFunc function for the Syncer. +func WithBatchPageRespConvertFunc[T, RESP any, V comparable](f func(resp *RESP) []T) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.batchPageRespConvertFunc = f + } +} + +// WithReqApiRouter sets the reqApiRouter for the Syncer. +func WithReqApiRouter[T, RESP any, V comparable](router string) Option[T, RESP, V] { + return func(s *Syncer[T, RESP, V]) { + s.reqApiRouter = router + } +} + +// NewSyncer creates a new Syncer with the provided options. +func NewSyncer[T, RESP any, V comparable](opts ...Option[T, RESP, V]) *Syncer[T, RESP, V] { + syncer := &Syncer[T, RESP, V]{} + for _, opt := range opts { + opt(syncer) + } + return syncer } // eq is a helper function to check equality of two data items. // It uses the equal function if provided; otherwise, it falls back to the cmp.Equal function. -func (s *Syncer[T, V]) eq(server T, local T) bool { +func (s *Syncer[T, RESP, V]) eq(server T, local T) bool { if s.equal != nil { return s.equal(server, local) } @@ -87,7 +213,7 @@ func (s *Syncer[T, V]) eq(server T, local T) bool { // onNotice is a helper function to handle notifications. // It calls the Syncer's notice function and the provided notice function in sequence if they are not nil. -func (s *Syncer[T, V]) onNotice(ctx context.Context, state int, server, local T, fn func(ctx context.Context, state int, server, local T) error) error { +func (s *Syncer[T, RESP, V]) onNotice(ctx context.Context, state int, server, local T, fn func(ctx context.Context, state int, server, local T) error) error { if s.notice != nil { if err := s.notice(ctx, state, server, local); err != nil { return err @@ -105,8 +231,8 @@ func (s *Syncer[T, V]) onNotice(ctx context.Context, state int, server, local T, // Sync synchronizes the data between the server and local storage. // It takes a context, two slices of data (serverData and localData), // a notice function to handle notifications during the sync process, -// and a variadic parameter noDel to control deletion behavior. -func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, notice func(ctx context.Context, state int, server, local T) error, noDel ...bool) (err error) { +// and a variadic parameter skipDeletion to control deletion behavior. +func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData []T, notice func(ctx context.Context, state int, server, local T) error, skipDeletionAndNotice ...bool) (err error) { defer func() { // Log the outcome of the synchronization process. if err == nil { @@ -115,6 +241,10 @@ func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, log.ZError(ctx, "sync failed", err, "type", s.ts) } }() + skipDeletion := false + if len(skipDeletionAndNotice) > 0 { + skipDeletion = skipDeletionAndNotice[0] + } // If both server and local data are empty, log and return. if len(serverData) == 0 && len(localData) == 0 { @@ -171,8 +301,8 @@ func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, } } - // Check the noDel flag; if set, skip deletion. - if len(noDel) > 0 && noDel[0] { + // Check the skipDeletion flag; if set, skip deletion. + if skipDeletion { return nil } @@ -191,3 +321,37 @@ func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, } return nil } + +func (s *Syncer[T, RESP, V]) FullSync(ctx context.Context, entityID string) (err error) { + defer func() { + // Log the outcome of the synchronization process. + if err == nil { + log.ZDebug(ctx, "full sync success", "type", s.ts) + } else { + log.ZError(ctx, "full sync failed", err, "type", s.ts) + } + }() + + //// If server data is empty, log and return + //if len(serverData) == 0 { + // log.ZDebug(ctx, "full sync server data is empty", "type", s.ts) + // return nil + //} + + // Clear local table data + if err = s.deleteAll(ctx, entityID); err != nil { + return errs.New("full sync delete all failed", "err", err.Error(), "type", s.ts) + } + + // Get batch req + batchReq := s.batchPageReq(entityID) + + // Batch page pull data and insert server data + if err = util.FetchAndInsertPagedData(ctx, s.reqApiRouter, batchReq, s.batchPageRespConvertFunc, + s.batchInsert, s.insert, 10000); err != nil { + return errs.New("full sync batch insert failed", "err", err.Error(), "type", s.ts) + } + + return nil + +} diff --git a/test/account.go b/test/account.go index 99b9ae0f3..fd969d778 100644 --- a/test/account.go +++ b/test/account.go @@ -17,7 +17,6 @@ package test import ( "context" "errors" - "fmt" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" @@ -86,9 +85,10 @@ var AdminToken = "" func init() { AdminToken = getToken("openIM123456") - if err := log.InitFromConfig("open-im-sdk-core", "", int(LogLevel), IsLogStandardOutput, false, LogFilePath, 0, 24); err != nil { - fmt.Println("123456", "log init failed ", err.Error()) + if err := log.InitFromConfig("open-im-sdk-core", "", int(LogLevel), IsLogStandardOutput, false, LogFilePath, 0, 24, "23432"); err != nil { + //fmt.Println("123456", "log init failed ", err.Error()) } + } var ctx context.Context From cb2b01cd3950a43a3e4f4a1f357ac2adf935493c Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:11:13 +0800 Subject: [PATCH 09/69] feat: implement db incr mirage. --- pkg/db/app_version.go | 37 ++++++++++++ pkg/db/db_init.go | 101 ++++++++++++++++++++++----------- pkg/db/db_interface/databse.go | 43 +++++++------- version | 1 + 4 files changed, 129 insertions(+), 53 deletions(-) create mode 100644 pkg/db/app_version.go create mode 100644 version diff --git a/pkg/db/app_version.go b/pkg/db/app_version.go new file mode 100644 index 000000000..649ef8dbc --- /dev/null +++ b/pkg/db/app_version.go @@ -0,0 +1,37 @@ +package db + +import ( + "context" + "errors" + "fmt" + + "github.com/openimsdk/tools/errs" + "gorm.io/gorm" + + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" +) + +func (d *DataBase) GetAppSDKVersion(ctx context.Context) (*model_struct.LocalAppSDKVersion, error) { + var appVersion model_struct.LocalAppSDKVersion + return &appVersion, errs.Wrap(d.conn.WithContext(ctx).Take(&appVersion).Error) +} + +func (d *DataBase) SetAppSDKVersion(ctx context.Context, appVersion *model_struct.LocalAppSDKVersion) error { + var exist model_struct.LocalAppSDKVersion + err := d.conn.WithContext(ctx).First(&exist).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + if createErr := d.conn.WithContext(ctx).Create(appVersion).Error; createErr != nil { + return errs.Wrap(createErr) + } + return nil + } else if err != nil { + return errs.Wrap(err) + } + + if updateErr := d.conn.WithContext(ctx).Model(&exist).Updates(appVersion).Error; updateErr != nil { + fmt.Println(updateErr) + return errs.Wrap(updateErr) + } + + return nil +} diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index e5cba7309..a09e176c1 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -19,7 +19,9 @@ package db import ( "context" + _ "embed" "errors" + "fmt" "path/filepath" "sync" "time" @@ -28,12 +30,16 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) +//go:embed../../version +var Version string + type DataBase struct { loginUserID string dbDir string @@ -47,7 +53,7 @@ type DataBase struct { } func (d *DataBase) GetMultipleMessageReactionExtension(ctx context.Context, msgIDList []string) (result []*model_struct.LocalChatLogReactionExtensions, err error) { - //TODO implement me + // TODO implement me panic("implement me") } @@ -128,32 +134,15 @@ func (d *DataBase) initDB(ctx context.Context, logLevel int) error { sqlDB.SetConnMaxIdleTime(time.Minute * 10) d.conn = db - err = db.AutoMigrate( - &model_struct.LocalFriend{}, - &model_struct.LocalFriendRequest{}, - &model_struct.LocalGroup{}, - &model_struct.LocalGroupMember{}, - &model_struct.LocalGroupRequest{}, - &model_struct.LocalErrChatLog{}, - &model_struct.LocalUser{}, - &model_struct.LocalBlack{}, - &model_struct.LocalConversation{}, - &model_struct.NotificationSeqs{}, - &model_struct.LocalChatLog{}, - &model_struct.LocalAdminGroupRequest{}, - &model_struct.LocalWorkMomentsNotification{}, - &model_struct.LocalWorkMomentsNotificationUnreadCount{}, - &model_struct.TempCacheLocalChatLog{}, - &model_struct.LocalChatLogReactionExtensions{}, - &model_struct.LocalUpload{}, - &model_struct.LocalStranger{}, - &model_struct.LocalSendingMessages{}, - &model_struct.LocalUserCommand{}, - &model_struct.LocalVersionSync{}, - ) - if err != nil { + // base + if err = db.AutoMigrate(&model_struct.LocalAppSDKVersion{}); err != nil { + return err + } + + if err = d.versionDataMigrate(ctx); err != nil { return err } + //if err := db.Table(constant.SuperGroupTableName).AutoMigrate(superGroup); err != nil { // return err //} @@ -161,13 +150,57 @@ func (d *DataBase) initDB(ctx context.Context, logLevel int) error { return nil } -func (d *DataBase) versionDataFix(ctx context.Context) { - //todo some model auto migrate data conversion - //conversationIDs, err := d.FindAllConversationConversationID(ctx) - //if err != nil { - // log.ZError(ctx, "FindAllConversationConversationID err", err) - //} - //for _, conversationID := range conversationIDs { - // d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).AutoMigrate(&model_struct.LocalChatLog{}) - //} +func (d *DataBase) versionDataMigrate(ctx context.Context) error { + verModel, err := d.GetAppSDKVersion(ctx) + log.ZDebug(ctx, "SDK err is", errs.Unwrap(err)) + if errors.Is(errs.Unwrap(err), gorm.ErrRecordNotFound) { + err = d.conn.AutoMigrate( + &model_struct.LocalAppSDKVersion{}, + &model_struct.LocalFriend{}, + &model_struct.LocalFriendRequest{}, + &model_struct.LocalGroup{}, + &model_struct.LocalGroupMember{}, + &model_struct.LocalGroupRequest{}, + &model_struct.LocalErrChatLog{}, + &model_struct.LocalUser{}, + &model_struct.LocalBlack{}, + &model_struct.LocalConversation{}, + &model_struct.NotificationSeqs{}, + &model_struct.LocalChatLog{}, + &model_struct.LocalAdminGroupRequest{}, + &model_struct.LocalWorkMomentsNotification{}, + &model_struct.LocalWorkMomentsNotificationUnreadCount{}, + &model_struct.TempCacheLocalChatLog{}, + &model_struct.LocalChatLogReactionExtensions{}, + &model_struct.LocalUpload{}, + &model_struct.LocalStranger{}, + &model_struct.LocalSendingMessages{}, + &model_struct.LocalUserCommand{}, + &model_struct.LocalVersionSync{}, + ) + if err != nil { + return err + } + err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: Version}) + if err != nil { + return err + } + + return nil + } else if err != nil { + return errs.Wrap(err) + } + if verModel.Version != Version { + switch Version { + case "3.8.0": + d.conn.AutoMigrate(&model_struct.LocalAppSDKVersion{}) + } + fmt.Println("now excute Set") + err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: Version}) + if err != nil { + return err + } + } + + return nil } diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index 68e8669fa..51530bb41 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -75,38 +75,38 @@ type GroupModel interface { type MessageModel interface { BatchInsertMessageList(ctx context.Context, conversationID string, MessageList []*model_struct.LocalChatLog) error - //BatchInsertMessageListController(ctx context.Context, MessageList []*model_struct.LocalChatLog) error + // BatchInsertMessageListController(ctx context.Context, MessageList []*model_struct.LocalChatLog) error InsertMessage(ctx context.Context, conversationID string, Message *model_struct.LocalChatLog) error - //InsertMessageController(ctx context.Context, message *model_struct.LocalChatLog) error + // InsertMessageController(ctx context.Context, message *model_struct.LocalChatLog) error SearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) - //SearchMessageByKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) + // SearchMessageByKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) SearchMessageByContentType(ctx context.Context, contentType []int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) - //SearchMessageByContentTypeController(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) + // SearchMessageByContentTypeController(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) - //SearchMessageByContentTypeAndKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) - //BatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error - //BatchSpecialUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error + // SearchMessageByContentTypeAndKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) + // BatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error + // BatchSpecialUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error MessageIfExists(ctx context.Context, ClientMsgID string) (bool, error) IsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error) GetMessage(ctx context.Context, conversationID, clientMsgID string) (*model_struct.LocalChatLog, error) GetMessageBySeq(ctx context.Context, conversationID string, seq int64) (*model_struct.LocalChatLog, error) - //GetMessageController(ctx context.Context, conversationID, clientMsgID string) (*model_struct.LocalChatLog, error) + // GetMessageController(ctx context.Context, conversationID, clientMsgID string) (*model_struct.LocalChatLog, error) UpdateColumnsMessageList(ctx context.Context, clientMsgIDList []string, args map[string]interface{}) error UpdateColumnsMessage(ctx context.Context, conversationID string, ClientMsgID string, args map[string]interface{}) error - //UpdateColumnsMessageController(ctx context.Context, ClientMsgID string, groupID string, sessionType int32, args map[string]interface{}) error + // UpdateColumnsMessageController(ctx context.Context, ClientMsgID string, groupID string, sessionType int32, args map[string]interface{}) error UpdateMessage(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error UpdateMessageBySeq(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error - //UpdateMessageController(ctx context.Context, c *model_struct.LocalChatLog) error + // UpdateMessageController(ctx context.Context, c *model_struct.LocalChatLog) error DeleteAllMessage(ctx context.Context) error UpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error - //UpdateMessageStatusBySourceIDController(ctx context.Context, sourceID string, status, sessionType int32) error + // UpdateMessageStatusBySourceIDController(ctx context.Context, sourceID string, status, sessionType int32) error UpdateMessageTimeAndStatus(ctx context.Context, conversationID, clientMsgID string, serverMsgID string, sendTime int64, status int32) error - //UpdateMessageTimeAndStatusController(ctx context.Context, msg *sdk_struct.MsgStruct) error + // UpdateMessageTimeAndStatusController(ctx context.Context, msg *sdk_struct.MsgStruct) error GetMessageList(ctx context.Context, conversationID string, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) - //GetMessageListController(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) + // GetMessageListController(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) GetMessageListNoTime(ctx context.Context, conversationID string, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) - //GetMessageListNoTimeController(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) + // GetMessageListNoTimeController(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) MarkConversationMessageAsReadDB(ctx context.Context, conversationID string, msgIDs []string) (rowsAffected int64, err error) MarkConversationMessageAsReadBySeqs(ctx context.Context, conversationID string, seqs []int64) (rowsAffected int64, err error) GetUnreadMessage(ctx context.Context, conversationID string) (result []*model_struct.LocalChatLog, err error) @@ -119,10 +119,10 @@ type MessageModel interface { GetTestMessage(ctx context.Context, seq uint32) (*model_struct.LocalChatLog, error) UpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error UpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error - //UpdateMsgSenderFaceURLAndSenderNicknameController(ctx context.Context, sendID, faceURL, nickname string, sessionType int) error + // UpdateMsgSenderFaceURLAndSenderNicknameController(ctx context.Context, sendID, faceURL, nickname string, sessionType int) error UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, conversationID, sendID, faceURL, nickname string) error GetMsgSeqByClientMsgID(ctx context.Context, clientMsgID string) (uint32, error) - //GetMsgSeqByClientMsgIDController(ctx context.Context, m *sdk_struct.MsgStruct) (uint32, error) + // GetMsgSeqByClientMsgIDController(ctx context.Context, m *sdk_struct.MsgStruct) (uint32, error) GetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error) GetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error) GetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error) @@ -141,7 +141,7 @@ type MessageModel interface { DeleteConversationAllMessages(ctx context.Context, conversationID string) error MarkDeleteConversationAllMessages(ctx context.Context, conversationID string) error SuperGroupSearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) - //SuperGroupSearchMessageByContentType(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) + // SuperGroupSearchMessageByContentType(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) SuperGroupSearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64, groupID string) (result []*model_struct.LocalChatLog, err error) SuperGroupBatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error @@ -158,7 +158,7 @@ type MessageModel interface { SuperGroupGetMessageListNoTime(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) SuperGroupGetSendingMessageList(ctx context.Context, groupID string) (result []*model_struct.LocalChatLog, err error) SuperGroupUpdateGroupMessageHasRead(ctx context.Context, msgIDList []string, groupID string) error - //SuperGroupUpdateGroupMessageFields(ctx context.Context, msgIDList []string, groupID string, args map[string]interface{}) error + // SuperGroupUpdateGroupMessageFields(ctx context.Context, msgIDList []string, groupID string, args map[string]interface{}) error SuperGroupUpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error SuperGroupUpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error @@ -172,7 +172,7 @@ type MessageModel interface { BatchInsertConversationUnreadMessageList(ctx context.Context, messageList []*model_struct.LocalConversationUnreadMessage) error DeleteConversationUnreadMessageList(ctx context.Context, conversationID string, sendTime int64) int64 DeleteConversationMsgs(ctx context.Context, conversationID string, msgIDs []string) error - //DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error + // DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error GetNotificationAllSeqs(ctx context.Context) ([]*model_struct.NotificationSeqs, error) } @@ -280,6 +280,10 @@ type VersionSyncModel interface { GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error) SetVersionSync(ctx context.Context, version *model_struct.LocalVersionSync) error } +type AppSDKVersion interface { + GetAppSDKVersion(ctx context.Context) (*model_struct.LocalAppSDKVersion, error) + SetAppSDKVersion(ctx context.Context, version *model_struct.LocalAppSDKVersion) error +} type DataBase interface { Close(ctx context.Context) error @@ -293,4 +297,5 @@ type DataBase interface { S3Model SendingMessagesModel VersionSyncModel + AppSDKVersion } diff --git a/version b/version new file mode 100644 index 000000000..240bba906 --- /dev/null +++ b/version @@ -0,0 +1 @@ +3.7.0 \ No newline at end of file From ec1751d4ae461dc5129c9e48beecf547ae06fea0 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:13:02 +0800 Subject: [PATCH 10/69] fix uncorrect schema. --- .goreleaser.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 3e443f5ce..9fa65aefb 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -58,8 +58,8 @@ builds: - amd64 - arm64 goarm: - - 6 - - 7 + - "6" + - "7" - id: openIM.wasm main: wasm/cmd/main.go # 指定 wasm 主文件路径 binary: openIM.wasm From d83ac7fb011d7d4442117b9b38c29b600086147e Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:28:16 +0800 Subject: [PATCH 11/69] refactor version structure. --- version => version/version | 0 version/version.go | 6 ++++++ 2 files changed, 6 insertions(+) rename version => version/version (100%) create mode 100644 version/version.go diff --git a/version b/version/version similarity index 100% rename from version rename to version/version diff --git a/version/version.go b/version/version.go new file mode 100644 index 000000000..23b3a82f5 --- /dev/null +++ b/version/version.go @@ -0,0 +1,6 @@ +package version + +import _ "embed" + +//go:embed version +var Version string From 828c42709ffa9f61abde2eaed513647fc48286c1 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:42:30 +0800 Subject: [PATCH 12/69] update version implement. --- pkg/db/db_init.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index a09e176c1..f933885c1 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -19,7 +19,6 @@ package db import ( "context" - _ "embed" "errors" "fmt" "path/filepath" @@ -29,6 +28,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/openim-sdk-core/v3/version" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -37,9 +37,6 @@ import ( "gorm.io/gorm/logger" ) -//go:embed../../version -var Version string - type DataBase struct { loginUserID string dbDir string @@ -181,22 +178,22 @@ func (d *DataBase) versionDataMigrate(ctx context.Context) error { if err != nil { return err } - err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: Version}) + err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: version.Version}) if err != nil { return err } return nil } else if err != nil { - return errs.Wrap(err) + return err } - if verModel.Version != Version { - switch Version { + if verModel.Version != version.Version { + switch version.Version { case "3.8.0": d.conn.AutoMigrate(&model_struct.LocalAppSDKVersion{}) } fmt.Println("now excute Set") - err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: Version}) + err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: version.Version}) if err != nil { return err } From 64f950129195120c80b8fd0a4f99617ec3885474 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:51:03 +0800 Subject: [PATCH 13/69] update error condition. --- pkg/db/app_version.go | 3 +-- pkg/db/db_init.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/db/app_version.go b/pkg/db/app_version.go index 649ef8dbc..9cb3cbe72 100644 --- a/pkg/db/app_version.go +++ b/pkg/db/app_version.go @@ -2,7 +2,6 @@ package db import ( "context" - "errors" "fmt" "github.com/openimsdk/tools/errs" @@ -19,7 +18,7 @@ func (d *DataBase) GetAppSDKVersion(ctx context.Context) (*model_struct.LocalApp func (d *DataBase) SetAppSDKVersion(ctx context.Context, appVersion *model_struct.LocalAppSDKVersion) error { var exist model_struct.LocalAppSDKVersion err := d.conn.WithContext(ctx).First(&exist).Error - if errors.Is(err, gorm.ErrRecordNotFound) { + if err == gorm.ErrRecordNotFound { if createErr := d.conn.WithContext(ctx).Create(appVersion).Error; createErr != nil { return errs.Wrap(createErr) } diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index f933885c1..d54e57fbf 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -150,7 +150,7 @@ func (d *DataBase) initDB(ctx context.Context, logLevel int) error { func (d *DataBase) versionDataMigrate(ctx context.Context) error { verModel, err := d.GetAppSDKVersion(ctx) log.ZDebug(ctx, "SDK err is", errs.Unwrap(err)) - if errors.Is(errs.Unwrap(err), gorm.ErrRecordNotFound) { + if errs.Unwrap(err) == gorm.ErrRecordNotFound { err = d.conn.AutoMigrate( &model_struct.LocalAppSDKVersion{}, &model_struct.LocalFriend{}, From ff72e1b9dcc798315389127e6c07ba0ada192d87 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 17 Jun 2024 19:55:28 +0800 Subject: [PATCH 14/69] remove fmt pkg. --- pkg/db/app_version.go | 2 -- pkg/db/db_init.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/pkg/db/app_version.go b/pkg/db/app_version.go index 9cb3cbe72..19d19888b 100644 --- a/pkg/db/app_version.go +++ b/pkg/db/app_version.go @@ -2,7 +2,6 @@ package db import ( "context" - "fmt" "github.com/openimsdk/tools/errs" "gorm.io/gorm" @@ -28,7 +27,6 @@ func (d *DataBase) SetAppSDKVersion(ctx context.Context, appVersion *model_struc } if updateErr := d.conn.WithContext(ctx).Model(&exist).Updates(appVersion).Error; updateErr != nil { - fmt.Println(updateErr) return errs.Wrap(updateErr) } diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index d54e57fbf..8641d3072 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -20,7 +20,6 @@ package db import ( "context" "errors" - "fmt" "path/filepath" "sync" "time" @@ -192,7 +191,6 @@ func (d *DataBase) versionDataMigrate(ctx context.Context) error { case "3.8.0": d.conn.AutoMigrate(&model_struct.LocalAppSDKVersion{}) } - fmt.Println("now excute Set") err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: version.Version}) if err != nil { return err From 307e17cec0f05f7b38637e92279bb969a34c6147 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 09:48:47 +0800 Subject: [PATCH 15/69] implement table struct. --- pkg/db/model_struct/data_model_struct.go | 29 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 3cd9771f8..1167aed5e 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -17,6 +17,7 @@ package model_struct import ( "database/sql/driver" "encoding/json" + "github.com/openimsdk/tools/errs" ) @@ -73,17 +74,17 @@ type LocalFriend struct { // int64 HandleTime = 8; // string Ex = 9; // } -// open_im_sdk.FriendRequest == imdb.FriendRequest +// open_im_sdk.FriendRequest == imdb.FriendRequest. type LocalFriendRequest struct { FromUserID string `gorm:"column:from_user_id;primary_key;type:varchar(64)" json:"fromUserID"` FromNickname string `gorm:"column:from_nickname;type:varchar;type:varchar(255)" json:"fromNickname"` FromFaceURL string `gorm:"column:from_face_url;type:varchar;type:varchar(255)" json:"fromFaceURL"` - //FromGender int32 `gorm:"column:from_gender" json:"fromGender"` + // FromGender int32 `gorm:"column:from_gender" json:"fromGender"` ToUserID string `gorm:"column:to_user_id;primary_key;type:varchar(64)" json:"toUserID"` ToNickname string `gorm:"column:to_nickname;type:varchar;type:varchar(255)" json:"toNickname"` ToFaceURL string `gorm:"column:to_face_url;type:varchar;type:varchar(255)" json:"toFaceURL"` - //ToGender int32 `gorm:"column:to_gender" json:"toGender"` + // ToGender int32 `gorm:"column:to_gender" json:"toGender"` HandleResult int32 `gorm:"column:handle_result" json:"handleResult"` ReqMsg string `gorm:"column:req_msg;type:varchar(255)" json:"reqMsg"` @@ -199,7 +200,7 @@ func (LocalGroupMember) TableName() string { // string HandleUserID = 7; // int64 HandleTime = 8; // string Ex = 9; -// }open_im_sdk.GroupRequest == imdb.GroupRequest +// }open_im_sdk.GroupRequest == imdb.GroupRequest. type LocalGroupRequest struct { GroupID string `gorm:"column:group_id;primary_key;type:varchar(64)" json:"groupID"` GroupName string `gorm:"column:group_name;size:255" json:"groupName"` @@ -216,7 +217,7 @@ type LocalGroupRequest struct { UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"` Nickname string `gorm:"column:nickname;type:varchar(255)" json:"nickname"` UserFaceURL string `gorm:"column:user_face_url;type:varchar(255)" json:"userFaceURL"` - //Gender int32 `gorm:"column:gender" json:"gender"` + // Gender int32 `gorm:"column:gender" json:"gender"` HandleResult int32 `gorm:"column:handle_result" json:"handleResult"` ReqMsg string `gorm:"column:req_msg;type:varchar(255)" json:"reqMsg"` @@ -240,7 +241,7 @@ type LocalGroupRequest struct { // string Ex = 8; // int64 CreateTime = 9; // int32 AppMangerLevel = 10; -// open_im_sdk.User == imdb.User +// open_im_sdk.User == imdb.User. type LocalUser struct { UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"` Nickname string `gorm:"column:name;type:varchar(255)" json:"nickname"` @@ -260,13 +261,13 @@ type LocalUser struct { // string OperatorUserID = 6; // string Ex = 7; // } -// open_im_sdk.BlackInfo(BlackUserInfo) != imdb.Black (BlockUserID) +// open_im_sdk.BlackInfo(BlackUserInfo) != imdb.Black (BlockUserID). type LocalBlack struct { OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:varchar(64)" json:"ownerUserID"` BlockUserID string `gorm:"column:block_user_id;primary_key;type:varchar(64)" json:"userID"` Nickname string `gorm:"column:nickname;type:varchar(255)" json:"nickname"` FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"` - //Gender int32 `gorm:"column:gender" json:"gender"` + // Gender int32 `gorm:"column:gender" json:"gender"` CreateTime int64 `gorm:"column:create_time" json:"createTime"` AddSource int32 `gorm:"column:add_source" json:"addSource"` OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"` @@ -402,7 +403,7 @@ type TempCacheLocalChatLog struct { // is_pinned int(10) NOT NULL , // PRIMARY KEY (conversation_id) // -// ) +// ). type LocalConversation struct { ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` @@ -447,7 +448,7 @@ type LocalConversationUnreadMessage struct { // string HandleUserID = 7; // int64 HandleTime = 8; // string Ex = 9; -// }open_im_sdk.GroupRequest == imdb.GroupRequest +// }open_im_sdk.GroupRequest == imdb.GroupRequest. type LocalAdminGroupRequest struct { LocalGroupRequest } @@ -572,3 +573,11 @@ type LocalVersionSync struct { func (LocalVersionSync) TableName() string { return "local_sync_version" } + +type LocalAppSDKVersion struct { + Version string `gorm:"column:version;type:varchar(255);primary_key" json:"version"` +} + +func (LocalAppSDKVersion) TableName() string { + return "local_app_sdk_version" +} From 39ef7dc03b75899ed2e66d3123f2a909c8e4c6b3 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 10:01:09 +0800 Subject: [PATCH 16/69] remove unnecessary comments. --- pkg/db/model_struct/data_model_struct.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 1167aed5e..b954d96ed 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -74,7 +74,7 @@ type LocalFriend struct { // int64 HandleTime = 8; // string Ex = 9; // } -// open_im_sdk.FriendRequest == imdb.FriendRequest. +// open_im_sdk.FriendRequest == imdb.FriendRequest type LocalFriendRequest struct { FromUserID string `gorm:"column:from_user_id;primary_key;type:varchar(64)" json:"fromUserID"` FromNickname string `gorm:"column:from_nickname;type:varchar;type:varchar(255)" json:"fromNickname"` @@ -200,7 +200,7 @@ func (LocalGroupMember) TableName() string { // string HandleUserID = 7; // int64 HandleTime = 8; // string Ex = 9; -// }open_im_sdk.GroupRequest == imdb.GroupRequest. +// }open_im_sdk.GroupRequest == imdb.GroupRequest type LocalGroupRequest struct { GroupID string `gorm:"column:group_id;primary_key;type:varchar(64)" json:"groupID"` GroupName string `gorm:"column:group_name;size:255" json:"groupName"` @@ -241,7 +241,7 @@ type LocalGroupRequest struct { // string Ex = 8; // int64 CreateTime = 9; // int32 AppMangerLevel = 10; -// open_im_sdk.User == imdb.User. +// open_im_sdk.User == imdb.User type LocalUser struct { UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"` Nickname string `gorm:"column:name;type:varchar(255)" json:"nickname"` @@ -261,7 +261,7 @@ type LocalUser struct { // string OperatorUserID = 6; // string Ex = 7; // } -// open_im_sdk.BlackInfo(BlackUserInfo) != imdb.Black (BlockUserID). +// open_im_sdk.BlackInfo(BlackUserInfo) != imdb.Black (BlockUserID) type LocalBlack struct { OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:varchar(64)" json:"ownerUserID"` BlockUserID string `gorm:"column:block_user_id;primary_key;type:varchar(64)" json:"userID"` @@ -403,7 +403,7 @@ type TempCacheLocalChatLog struct { // is_pinned int(10) NOT NULL , // PRIMARY KEY (conversation_id) // -// ). +// ) type LocalConversation struct { ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` @@ -448,7 +448,7 @@ type LocalConversationUnreadMessage struct { // string HandleUserID = 7; // int64 HandleTime = 8; // string Ex = 9; -// }open_im_sdk.GroupRequest == imdb.GroupRequest. +// }open_im_sdk.GroupRequest == imdb.GroupRequest type LocalAdminGroupRequest struct { LocalGroupRequest } From c8cb470f140aab677d62e2aeb28ec9e236a924cb Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:01:36 +0800 Subject: [PATCH 17/69] feat: group member full sync and incr sync. --- internal/group/notification.go | 251 +++++++++++++++++++++++++++++++++ internal/group/sdk.go | 26 +++- pkg/datafetcher/datafetcher.go | 97 +++++++++++++ pkg/db/version_sync.go | 3 +- 4 files changed, 374 insertions(+), 3 deletions(-) create mode 100644 pkg/datafetcher/datafetcher.go diff --git a/internal/group/notification.go b/internal/group/notification.go index 9deae25fb..b832b3926 100644 --- a/internal/group/notification.go +++ b/internal/group/notification.go @@ -21,6 +21,8 @@ import ( "fmt" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" @@ -281,3 +283,252 @@ func (g *Group) doNotification(ctx context.Context, msg *sdkws.MsgData) error { return fmt.Errorf("unknown tips type: %d", msg.ContentType) } } + +func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { + switch msg.ContentType { + case constant.GroupCreatedNotification: // 1501 + var detail sdkws.GroupCreatedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + + if err := g.IncrSyncJoinGroup(ctx); err != nil { + return err + } + return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + + case constant.GroupInfoSetNotification: // 1502 + var detail sdkws.GroupInfoSetTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.IncrSyncJoinGroup(ctx) + case constant.JoinGroupApplicationNotification: // 1503 + var detail sdkws.JoinGroupApplicationTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + if detail.Applicant.UserID == g.loginUserID { + return g.SyncSelfGroupApplications(ctx, detail.Group.GroupID) + } else { + return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) + } + case constant.GroupApplicationAcceptedNotification: // 1505 + var detail sdkws.GroupApplicationAcceptedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + switch detail.ReceiverAs { + case 0: + return g.SyncAllSelfGroupApplication(ctx) + case 1: + return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) + default: + return fmt.Errorf("GroupApplicationAcceptedNotification ReceiverAs unknown %d", detail.ReceiverAs) + } + case constant.GroupApplicationRejectedNotification: // 1506 + var detail sdkws.GroupApplicationRejectedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + switch detail.ReceiverAs { + case 0: + return g.SyncAllSelfGroupApplication(ctx) + case 1: + return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) + default: + return fmt.Errorf("GroupApplicationRejectedNotification ReceiverAs unknown %d", detail.ReceiverAs) + } + case constant.GroupOwnerTransferredNotification: // 1507 + var detail sdkws.GroupOwnerTransferredTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + if err := g.IncrSyncJoinGroup(ctx); err != nil { + return err + } + if detail.Group == nil { + return errs.New(fmt.Sprintf("group is nil, groupID: %s", detail.Group.GroupID)) + } + return g.SyncAllGroupMember(ctx, detail.Group.GroupID) + case constant.MemberKickedNotification: // 1508 + var detail sdkws.MemberKickedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + var self bool + for _, info := range detail.KickedUserList { + if info.UserID == g.loginUserID { + self = true + break + } + } + if self { + members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) + if err != nil { + return err + } + if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { + return err + } + for _, member := range members { + data, err := json.Marshal(member) + if err != nil { + return err + } + g.listener().OnGroupMemberDeleted(string(data)) + } + group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) + if err != nil { + return err + } + group.MemberCount = 0 + data, err := json.Marshal(group) + if err != nil { + return err + } + if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { + return err + } + g.listener().OnGroupInfoChanged(string(data)) + g.listener().OnJoinedGroupDeleted(string(data)) + return nil + } else { + var userIDs []string + for _, info := range detail.KickedUserList { + userIDs = append(userIDs, info.UserID) + } + return g.SyncGroupMembers(ctx, detail.Group.GroupID, userIDs...) + } + case constant.MemberQuitNotification: // 1504 + var detail sdkws.MemberQuitTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + if detail.QuitUser.UserID == g.loginUserID { + members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) + if err != nil { + return err + } + if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { + return err + } + for _, member := range members { + data, err := json.Marshal(member) + if err != nil { + return err + } + g.listener().OnGroupMemberDeleted(string(data)) + } + group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) + if err != nil { + return err + } + group.MemberCount = 0 + data, err := json.Marshal(group) + if err != nil { + return err + } + if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { + return err + } + g.listener().OnGroupInfoChanged(string(data)) + return nil + } else { + //return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, nil, nil, detail.GroupMemberVersion) + } + case constant.MemberInvitedNotification: // 1509 + var detail sdkws.MemberInvitedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + userIDMap := datautil.SliceSetAny(detail.InvitedUserList, func(e *sdkws.GroupMemberFullInfo) string { + return e.UserID + }) + //自己也是被邀请的一员 + if _, ok := userIDMap[g.loginUserID]; ok { + if err := g.IncrSyncJoinGroup(ctx); err != nil { + return err + } + return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + } else { + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, detail.InvitedUserList, detail.GroupMemberVersion) + } + case constant.MemberEnterNotification: // 1510 + var detail sdkws.MemberEnterTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + if detail.EntrantUser.UserID == g.loginUserID { + if err := g.IncrSyncJoinGroup(ctx); err != nil { + return err + } + return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + } else { + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, []*sdkws.GroupMemberFullInfo{detail.EntrantUser}, detail.GroupMemberVersion) + } + case constant.GroupDismissedNotification: // 1511 + var detail sdkws.GroupDismissedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + g.listener().OnGroupDismissed(utils.StructToJsonString(detail.Group)) + if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { + return err + } + if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { + return err + } + return g.SyncAllGroupMember(ctx, detail.Group.GroupID) + case constant.GroupMemberMutedNotification: // 1512 + var detail sdkws.GroupMemberMutedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) + case constant.GroupMemberCancelMutedNotification: // 1513 + var detail sdkws.GroupMemberCancelMutedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) + case constant.GroupMutedNotification: // 1514 + return g.SyncGroups(ctx, msg.GroupID) + case constant.GroupCancelMutedNotification: // 1515 + return g.SyncGroups(ctx, msg.GroupID) + case constant.GroupMemberInfoSetNotification: // 1516 + var detail sdkws.GroupMemberInfoSetTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + + return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) //detail.ChangedUser.UserID + case constant.GroupMemberSetToAdminNotification: // 1517 + var detail sdkws.GroupMemberInfoSetTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) + case constant.GroupMemberSetToOrdinaryUserNotification: // 1518 + var detail sdkws.GroupMemberInfoSetTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) + case constant.GroupInfoSetAnnouncementNotification: // 1519 + var detail sdkws.GroupInfoSetAnnouncementTips // + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroups(ctx, detail.Group.GroupID) + case constant.GroupInfoSetNameNotification: // 1520 + var detail sdkws.GroupInfoSetNameTips // + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.SyncGroups(ctx, detail.Group.GroupID) + default: + return fmt.Errorf("unknown tips type: %d", msg.ContentType) + } +} diff --git a/internal/group/sdk.go b/internal/group/sdk.go index e79512d50..05e0c32c9 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -16,6 +16,7 @@ package group import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" "github.com/openimsdk/tools/utils/datautil" "time" @@ -250,7 +251,30 @@ func (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdkws.GroupInfoForS } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupMemberListSplit(ctx, groupID, filter, int(offset), int(count)) + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupMemberTableName(), + groupID, + func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }, + func(ctx context.Context, uids []string) ([]*model_struct.LocalGroupMember, error) { + //todo GetGroupMemberListSplit change to + return g.db.GetGroupMemberListSplit(ctx, groupID, filter, int(offset), int(count)) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil + }, + ) + return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) + } func (g *Group) GetGroupMemberOwnerAndAdmin(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go new file mode 100644 index 000000000..8ca01ba40 --- /dev/null +++ b/pkg/datafetcher/datafetcher.go @@ -0,0 +1,97 @@ +package datafetcher + +import ( + "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" +) + +// DataFetcher is a struct that handles data synchronization +type DataFetcher[T any] struct { + db db_interface.VersionSyncModel + TabName string + EntityID string + Key func(T) string + batchInsert func(ctx context.Context, servers []T) error + FetchFromLocal FetchDataFunc[T] + fetchFromServer FetchFromServerFunc[T] +} + +// FetchDataFunc is a function type for fetching data +type FetchDataFunc[T any] func(ctx context.Context, uids []string) ([]T, error) + +// FetchFromServerFunc is a function type for fetching data from server +type FetchFromServerFunc[T any] func(ctx context.Context, uids []string) ([]T, error) + +// NewDataFetcher creates a new NewDataFetcher +func NewDataFetcher[T any](db db_interface.VersionSyncModel, tabName string, entityID string, key func(T) string, + batchInsert func(ctx context.Context, servers []T) error, fetchFromLocal FetchDataFunc[T], fetchFromServer FetchFromServerFunc[T]) *DataFetcher[T] { + return &DataFetcher[T]{ + db: db, + TabName: tabName, + EntityID: entityID, + Key: key, + batchInsert: batchInsert, + FetchFromLocal: fetchFromLocal, + fetchFromServer: fetchFromServer, + } +} + +// FetchWithPagination fetches data with pagination and fills missing data from server +func (ds *DataFetcher[T]) FetchWithPagination(ctx context.Context, offset, limit int) ([]T, error) { + versionInfo, err := ds.db.GetVersionSync(ctx, ds.TabName, ds.EntityID) + if err != nil { + return nil, err + } + + if offset > len(versionInfo.UIDList) { + return nil, errs.New("offset exceeds the length of the UID list").Wrap() + } + + end := offset + limit + if end > len(versionInfo.UIDList) { + end = len(versionInfo.UIDList) + } + + paginatedUIDs := versionInfo.UIDList[offset:end] + + localData, err := ds.FetchMissingAndFillLocal(ctx, paginatedUIDs) + if err != nil { + return nil, err + } + + return localData, nil +} + +// FetchMissingAndFillLocal fetches missing data from server and fills local database +func (ds *DataFetcher[T]) FetchMissingAndFillLocal(ctx context.Context, uids []string) ([]T, error) { + localData, err := ds.FetchFromLocal(ctx, uids) + if err != nil { + return nil, err + } + + localUIDSet := datautil.SliceSetAny(localData, ds.Key) + + var missingUIDs []string + for _, uid := range uids { + if _, found := localUIDSet[uid]; !found { + missingUIDs = append(missingUIDs, uid) + } + } + + if len(missingUIDs) > 0 { + serverData, err := ds.fetchFromServer(ctx, missingUIDs) + if err != nil { + return nil, err + } + + if err := ds.batchInsert(ctx, serverData); err != nil { + return nil, err + } + + localData = append(localData, serverData...) + } + + return localData, nil +} diff --git a/pkg/db/version_sync.go b/pkg/db/version_sync.go index ade89aa24..3425c0fdb 100644 --- a/pkg/db/version_sync.go +++ b/pkg/db/version_sync.go @@ -2,7 +2,6 @@ package db import ( "context" - "errors" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/tools/errs" "gorm.io/gorm" @@ -22,7 +21,7 @@ func (d *DataBase) SetVersionSync(ctx context.Context, lv *model_struct.LocalVer var existing model_struct.LocalVersionSync err := d.conn.WithContext(ctx).Where("`table` = ? AND `entity_id` = ?", lv.Table, lv.EntityID).First(&existing).Error - if errors.Is(err, gorm.ErrRecordNotFound) { + if err == gorm.ErrRecordNotFound { if createErr := d.conn.WithContext(ctx).Create(lv).Error; createErr != nil { return errs.Wrap(createErr) } From cecbda194073e86f9cfbcc56ccad0c90db2ddd96 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 12:32:36 +0800 Subject: [PATCH 18/69] feat: implement method in group member. --- pkg/db/db_interface/databse.go | 2 ++ pkg/db/group_member_model.go | 35 +++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index 51530bb41..b64d3af27 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -16,6 +16,7 @@ package db_interface import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" ) @@ -57,6 +58,7 @@ type GroupModel interface { GetGroupAdminID(ctx context.Context, groupID string) ([]string, error) GetGroupMemberListByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) GetGroupMemberListSplit(ctx context.Context, groupID string, filter int32, offset, count int) ([]*model_struct.LocalGroupMember, error) + GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error) GetGroupMemberOwnerAndAdminDB(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) GetGroupMemberOwner(ctx context.Context, groupID string) (*model_struct.LocalGroupMember, error) GetGroupMemberListSplitByJoinTimeFilter(ctx context.Context, groupID string, offset, count int, joinTimeBegin, joinTimeEnd int64, userIDList []string) ([]*model_struct.LocalGroupMember, error) diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 1d9bffc1e..141c1dbc5 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -21,9 +21,11 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetGroupMemberInfoByGroupIDUserID(ctx context.Context, groupID, userID string) (*model_struct.LocalGroupMember, error) { @@ -86,6 +88,37 @@ func (d *DataBase) GetGroupMemberListByGroupID(ctx context.Context, groupID stri } return transfer, utils.Wrap(err, "GetGroupMemberListByGroupID failed ") } + +func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + d.groupMtx.Lock() + defer d.groupMtx.Unlock() + var groupMemberList []model_struct.LocalGroupMember + var err error + switch filter { + case constant.GroupFilterAll: + err = d.conn.WithContext(ctx).Where("group_id = ? AND user_id IN ?", groupID, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error + case constant.GroupFilterOwner: + err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOwner, userIDs).Find(&groupMemberList).Error + case constant.GroupFilterAdmin: + err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupAdmin, userIDs).Order("join_time ASC").Find(&groupMemberList).Error + case constant.GroupFilterOrdinaryUsers: + err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOrdinaryUsers, userIDs).Order("join_time ASC").Find(&groupMemberList).Error + case constant.GroupFilterAdminAndOrdinaryUsers: + err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupAdmin, constant.GroupOrdinaryUsers, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error + case constant.GroupFilterOwnerAndAdmin: + err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupOwner, constant.GroupAdmin, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error + default: + return nil, errs.New("filter args failed.", "filter", filter).Wrap() + } + var transfer []*model_struct.LocalGroupMember + for _, member := range groupMemberList { + memberCopy := member + transfer = append(transfer, &memberCopy) + } + return transfer, errs.Wrap(err) + +} + func (d *DataBase) GetGroupMemberListSplit(ctx context.Context, groupID string, filter int32, offset, count int) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() @@ -105,7 +138,7 @@ func (d *DataBase) GetGroupMemberListSplit(ctx context.Context, groupID string, case constant.GroupFilterOwnerAndAdmin: err = d.conn.WithContext(ctx).Where("group_id = ? And (role_level = ? or role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error default: - return nil, fmt.Errorf("filter args failed %d", filter) + return nil, errs.New("filter args failed", "filter", filter).Wrap() } var transfer []*model_struct.LocalGroupMember for _, v := range groupMemberList { From e3140606417b65ec29090e73e93fde91baa04a14 Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:09:59 +0800 Subject: [PATCH 19/69] feat: group member full sync and incr sync. --- internal/group/group.go | 30 +-------- internal/group/notification.go | 109 ++++++++------------------------- internal/group/sdk.go | 81 +++--------------------- open_im_sdk/userRelated.go | 1 - pkg/db/db_interface/databse.go | 4 +- pkg/db/version_sync.go | 7 +++ 6 files changed, 48 insertions(+), 184 deletions(-) diff --git a/internal/group/group.go b/internal/group/group.go index 3d33bfac9..48fb831ed 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -70,6 +70,9 @@ func (g *Group) initSyncer() { if err := g.db.DeleteGroupAllMembers(ctx, value.GroupID); err != nil { return err } + if err := g.db.DeleteVersionSync(ctx, g.groupMemberTableName(), value.GroupID); err != nil { + return err + } return g.db.DeleteGroup(ctx, value.GroupID) }), syncer.WithUpdate[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(ctx context.Context, server, local *model_struct.LocalGroup) error { @@ -337,30 +340,3 @@ func (g *Group) GetJoinedDiffusionGroupIDListFromSvr(ctx context.Context) ([]str } return groupIDs, nil } - -func (g *Group) DeleteGroupAndMemberInfo(ctx context.Context) { - memberGroupIDs, err := g.db.GetGroupMemberAllGroupIDs(ctx) - if err != nil { - log.ZError(ctx, "GetGroupMemberAllGroupIDs failed", err) - return - } - if len(memberGroupIDs) > 0 { - groups, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - log.ZError(ctx, "GetJoinedGroupListDB failed", err) - return - } - memberGroupIDMap := make(map[string]struct{}) - for _, groupID := range memberGroupIDs { - memberGroupIDMap[groupID] = struct{}{} - } - for _, info := range groups { - delete(memberGroupIDMap, info.GroupID) - } - for groupID := range memberGroupIDMap { - if err := g.db.DeleteGroupAllMembers(ctx, groupID); err != nil { - log.ZError(ctx, "DeleteGroupAllMembers failed", err, "groupID", groupID) - } - } - } -} diff --git a/internal/group/notification.go b/internal/group/notification.go index b832b3926..2d08da478 100644 --- a/internal/group/notification.go +++ b/internal/group/notification.go @@ -350,7 +350,7 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { if detail.Group == nil { return errs.New(fmt.Sprintf("group is nil, groupID: %s", detail.Group.GroupID)) } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) + return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) case constant.MemberKickedNotification: // 1508 var detail sdkws.MemberKickedTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { @@ -364,41 +364,10 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { } } if self { - members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) - if err != nil { - return err - } - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - for _, member := range members { - data, err := json.Marshal(member) - if err != nil { - return err - } - g.listener().OnGroupMemberDeleted(string(data)) - } - group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) - if err != nil { - return err - } - group.MemberCount = 0 - data, err := json.Marshal(group) - if err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - g.listener().OnGroupInfoChanged(string(data)) - g.listener().OnJoinedGroupDeleted(string(data)) - return nil + return g.IncrSyncJoinGroup(ctx) } else { - var userIDs []string - for _, info := range detail.KickedUserList { - userIDs = append(userIDs, info.UserID) - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, userIDs...) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + detail.KickedUserList, nil, detail.GroupMemberVersion) } case constant.MemberQuitNotification: // 1504 var detail sdkws.MemberQuitTips @@ -406,37 +375,11 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { return err } if detail.QuitUser.UserID == g.loginUserID { - members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) - if err != nil { - return err - } - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - for _, member := range members { - data, err := json.Marshal(member) - if err != nil { - return err - } - g.listener().OnGroupMemberDeleted(string(data)) - } - group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) - if err != nil { - return err - } - group.MemberCount = 0 - data, err := json.Marshal(group) - if err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - g.listener().OnGroupInfoChanged(string(data)) - return nil + return g.IncrSyncJoinGroup(ctx) } else { //return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, nil, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, + nil, nil, detail.GroupMemberVersion) } case constant.MemberInvitedNotification: // 1509 var detail sdkws.MemberInvitedTips @@ -453,7 +396,8 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { } return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) } else { - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, detail.InvitedUserList, detail.GroupMemberVersion) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, + detail.InvitedUserList, detail.GroupMemberVersion) } case constant.MemberEnterNotification: // 1510 var detail sdkws.MemberEnterTips @@ -466,7 +410,8 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { } return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) } else { - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, []*sdkws.GroupMemberFullInfo{detail.EntrantUser}, detail.GroupMemberVersion) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, + []*sdkws.GroupMemberFullInfo{detail.EntrantUser}, detail.GroupMemberVersion) } case constant.GroupDismissedNotification: // 1511 var detail sdkws.GroupDismissedTips @@ -474,60 +419,60 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { return err } g.listener().OnGroupDismissed(utils.StructToJsonString(detail.Group)) - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) + + return g.IncrSyncJoinGroup(ctx) case constant.GroupMemberMutedNotification: // 1512 var detail sdkws.GroupMemberMutedTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, detail.GroupMemberVersion) case constant.GroupMemberCancelMutedNotification: // 1513 var detail sdkws.GroupMemberCancelMutedTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, detail.GroupMemberVersion) case constant.GroupMutedNotification: // 1514 - return g.SyncGroups(ctx, msg.GroupID) + return g.IncrSyncJoinGroup(ctx) case constant.GroupCancelMutedNotification: // 1515 - return g.SyncGroups(ctx, msg.GroupID) + return g.IncrSyncJoinGroup(ctx) case constant.GroupMemberInfoSetNotification: // 1516 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) //detail.ChangedUser.UserID + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) case constant.GroupMemberSetToAdminNotification: // 1517 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) case constant.GroupMemberSetToOrdinaryUserNotification: // 1518 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) + return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) case constant.GroupInfoSetAnnouncementNotification: // 1519 var detail sdkws.GroupInfoSetAnnouncementTips // if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroups(ctx, detail.Group.GroupID) + return g.IncrSyncJoinGroup(ctx) case constant.GroupInfoSetNameNotification: // 1520 var detail sdkws.GroupInfoSetNameTips // if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroups(ctx, detail.Group.GroupID) + return g.IncrSyncJoinGroup(ctx) default: return fmt.Errorf("unknown tips type: %d", msg.ContentType) } diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 05e0c32c9..f387f4c75 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -32,36 +32,6 @@ import ( "github.com/openimsdk/protocol/wrapperspb" ) -// // deprecated use CreateGroup -// funcation (g *Group) CreateGroup(ctx context.Context, groupBaseInfo sdk_params_callback.CreateGroupBaseInfoParam, memberList sdk_params_callback.CreateGroupMemberRoleParam) (*sdkws.GroupInfo, error) { -// req := &group.CreateGroupReq{ -// GroupInfo: &sdkws.GroupInfo{ -// GroupName: groupBaseInfo.GroupName, -// Notification: groupBaseInfo.Notification, -// Introduction: groupBaseInfo.Introduction, -// FaceURL: groupBaseInfo.FaceURL, -// Ex: groupBaseInfo.Ex, -// GroupType: groupBaseInfo.GroupType, -// }, -// } -// if groupBaseInfo.NeedVerification != nil { -// req.GroupInfo.NeedVerification = *groupBaseInfo.NeedVerification -// } -// for _, info := range memberList { -// switch info.RoleLevel { -// case constant.GroupOrdinaryUsers: -// req.InitMembers = append(req.InitMembers, info.UserID) -// case constant.GroupOwner: -// req.OwnerUserID = info.UserID -// case constant.GroupAdmin: -// req.AdminUserIDs = append(req.AdminUserIDs, info.UserID) -// default: -// return nil, sdkerrs.ErrArgs.Wrap(fmt.Sprintf("CreateGroup: invalid role level %d", info.RoleLevel)) -// } -// } -// return g.CreateGroup(ctx, req) -// } - func (g *Group) CreateGroup(ctx context.Context, req *group.CreateGroupReq) (*sdkws.GroupInfo, error) { if req.OwnerUserID == "" { req.OwnerUserID = g.loginUserID @@ -74,10 +44,10 @@ func (g *Group) CreateGroup(ctx context.Context, req *group.CreateGroupReq) (*sd if err != nil { return nil, err } - if err := g.SyncGroups(ctx, resp.GroupInfo.GroupID); err != nil { + if err := g.IncrSyncJoinGroup(ctx); err != nil { return nil, err } - if err := g.SyncAllGroupMember(ctx, resp.GroupInfo.GroupID); err != nil { + if err := g.IncrSyncGroupMember(ctx, resp.GroupInfo.GroupID); err != nil { return nil, err } return resp.GroupInfo, nil @@ -90,12 +60,6 @@ func (g *Group) JoinGroup(ctx context.Context, groupID, reqMsg string, joinSourc if err := g.SyncSelfGroupApplications(ctx, groupID); err != nil { return err } - // if err := g.SyncJoinedGroup(ctx); err != nil { - // return err - // } - // if err := g.SyncGroupMember(ctx, groupID); err != nil { - // return err - // } return nil } @@ -103,15 +67,6 @@ func (g *Group) QuitGroup(ctx context.Context, groupID string) error { if err := util.ApiPost(ctx, constant.QuitGroupRouter, &group.QuitGroupReq{GroupID: groupID}, nil); err != nil { return err } - if err := g.db.DeleteGroupAllMembers(ctx, groupID); err != nil { - return err - } - if err := g.deleteGroup(ctx, groupID); err != nil { - return err - } - // if err := g.SyncGroupMember(ctx, groupID); err != nil { - // return err - // } return nil } @@ -119,12 +74,6 @@ func (g *Group) DismissGroup(ctx context.Context, groupID string) error { if err := util.ApiPost(ctx, constant.DismissGroupRouter, &group.DismissGroupReq{GroupID: groupID}, nil); err != nil { return err } - if err := g.deleteGroup(ctx, groupID); err != nil { - return err - } - if err := g.db.DeleteGroupAllMembers(ctx, groupID); err != nil { - return err - } return nil } @@ -137,7 +86,7 @@ func (g *Group) ChangeGroupMute(ctx context.Context, groupID string, isMute bool if err != nil { return err } - if err := g.SyncGroups(ctx, groupID); err != nil { + if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } return nil @@ -152,12 +101,6 @@ func (g *Group) ChangeGroupMemberMute(ctx context.Context, groupID, userID strin if err != nil { return err } - if err := g.SyncGroups(ctx, groupID); err != nil { - return err - } - if err := g.SyncGroupMembers(ctx, groupID, userID); err != nil { - return err - } return nil } @@ -173,7 +116,7 @@ func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.S if err := util.ApiPost(ctx, constant.SetGroupMemberInfoRouter, &group.SetGroupMemberInfoReq{Members: []*group.SetGroupMemberInfo{groupMemberInfo}}, nil); err != nil { return err } - return g.SyncGroupMembers(ctx, groupMemberInfo.GroupID, groupMemberInfo.UserID) + return g.IncrSyncGroupMember(ctx, groupMemberInfo.GroupID) } func (g *Group) GetJoinedGroupList(ctx context.Context) ([]*model_struct.LocalGroup, error) { @@ -247,7 +190,7 @@ func (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdkws.GroupInfoForS if err := util.ApiPost(ctx, constant.SetGroupInfoRouter, &group.SetGroupInfoReq{GroupInfoForSet: groupInfo}, nil); err != nil { return err } - return g.SyncGroups(ctx, groupInfo.GroupID) + return g.IncrSyncJoinGroup(ctx) } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { @@ -296,21 +239,17 @@ func (g *Group) KickGroupMember(ctx context.Context, groupID string, reason stri if err := util.ApiPost(ctx, constant.KickGroupMemberRouter, &group.KickGroupMemberReq{GroupID: groupID, KickedUserIDs: userIDList, Reason: reason}, nil); err != nil { return err } - return g.SyncGroupMembers(ctx, groupID, userIDList...) + return g.IncrSyncGroupMember(ctx, groupID) } func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID string) error { - oldOwner, err := g.db.GetGroupMemberOwner(ctx, groupID) - if err != nil { - return err - } if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { return err } - if err := g.SyncGroups(ctx, groupID); err != nil { + if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - if err := g.SyncGroupMembers(ctx, groupID, newOwnerUserID, oldOwner.UserID); err != nil { + if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { return err } return nil @@ -320,10 +259,10 @@ func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, u if err := util.ApiPost(ctx, constant.InviteUserToGroupRouter, &group.InviteUserToGroupReq{GroupID: groupID, Reason: reason, InvitedUserIDs: userIDList}, nil); err != nil { return err } - if err := g.SyncGroups(ctx, groupID); err != nil { + if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - if err := g.SyncGroupMembers(ctx, groupID, userIDList...); err != nil { + if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { return err } return nil diff --git a/open_im_sdk/userRelated.go b/open_im_sdk/userRelated.go index c4b6a366d..c8110431c 100644 --- a/open_im_sdk/userRelated.go +++ b/open_im_sdk/userRelated.go @@ -380,7 +380,6 @@ func (u *LoginMgr) run(ctx context.Context) { u.longConnMgr.Run(ctx) go u.msgSyncer.DoListener(ctx) go common.DoListener(u.conversation, u.ctx) - go u.group.DeleteGroupAndMemberInfo(ctx) go u.logoutListener(ctx) } diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index 51530bb41..ebdad8d41 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -83,9 +83,6 @@ type MessageModel interface { SearchMessageByContentType(ctx context.Context, contentType []int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) // SearchMessageByContentTypeController(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) - // SearchMessageByContentTypeAndKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) - // BatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error - // BatchSpecialUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error MessageIfExists(ctx context.Context, ClientMsgID string) (bool, error) IsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error) @@ -279,6 +276,7 @@ type SendingMessagesModel interface { type VersionSyncModel interface { GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error) SetVersionSync(ctx context.Context, version *model_struct.LocalVersionSync) error + DeleteVersionSync(ctx context.Context, tableName, entityID string) error } type AppSDKVersion interface { GetAppSDKVersion(ctx context.Context) (*model_struct.LocalAppSDKVersion, error) diff --git a/pkg/db/version_sync.go b/pkg/db/version_sync.go index 3425c0fdb..07ff73e8a 100644 --- a/pkg/db/version_sync.go +++ b/pkg/db/version_sync.go @@ -36,3 +36,10 @@ func (d *DataBase) SetVersionSync(ctx context.Context, lv *model_struct.LocalVer return nil } + +func (d *DataBase) DeleteVersionSync(ctx context.Context, tableName, entityID string) error { + d.versionMtx.Lock() + defer d.versionMtx.Unlock() + localVersionSync := model_struct.LocalVersionSync{Table: tableName, EntityID: entityID} + return errs.WrapMsg(d.conn.WithContext(ctx).Delete(&localVersionSync).Error, "DeleteVersionSync failed") +} From b5fb7f5b951263a006715fce164cd3f0a677a523 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 18:12:52 +0800 Subject: [PATCH 20/69] fix uncorrect field name. --- internal/group/sync2.go | 27 ++++++++++++++------------- internal/incrversion/option.go | 12 ++++++------ msgtest/module/friend_manager.go | 3 ++- msgtest/pressure_test.go | 7 ++++--- pkg/datafetcher/datafetcher.go | 9 +++++---- 5 files changed, 31 insertions(+), 27 deletions(-) diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 3151e55ef..58e522ec6 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -2,6 +2,8 @@ package group import ( "context" + "sync" + "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -12,7 +14,6 @@ import ( "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" - "sync" ) type BatchIncrementalReq struct { @@ -109,10 +110,10 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group.GetIncrementalGroupMemberResp) error { groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ - Ctx: ctx, - DB: g.db, - TabName: g.groupMemberTableName(), - EntityID: groupID, + Ctx: ctx, + DB: g.db, + TableName: g.groupMemberTableName(), + EntityID: groupID, Key: func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID }, @@ -158,10 +159,10 @@ func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delete, update, insert []*sdkws.GroupMemberFullInfo, version uint64) error { groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ - Ctx: ctx, - DB: g.db, - TabName: g.groupMemberTableName(), - EntityID: groupID, + Ctx: ctx, + DB: g.db, + TableName: g.groupMemberTableName(), + EntityID: groupID, Key: func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID }, @@ -235,10 +236,10 @@ func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delet func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { opt := incrversion.VersionSynchronizer[*model_struct.LocalGroup, *group.GetIncrementalJoinGroupResp]{ - Ctx: ctx, - DB: g.db, - TabName: g.groupTableName(), - EntityID: g.loginUserID, + Ctx: ctx, + DB: g.db, + TableName: g.groupTableName(), + EntityID: g.loginUserID, Key: func(LocalGroup *model_struct.LocalGroup) string { return LocalGroup.GroupID }, diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index 38771d36e..c961433e2 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -14,7 +14,7 @@ import ( type VersionSynchronizer[V, R any] struct { Ctx context.Context DB db_interface.VersionSyncModel - TabName string + TableName string EntityID string Key func(V) string Local func() ([]V, error) @@ -31,7 +31,7 @@ type VersionSynchronizer[V, R any] struct { } func (o *VersionSynchronizer[V, R]) getVersionInfo() (*model_struct.LocalVersionSync, error) { - versionInfo, err := o.DB.GetVersionSync(o.Ctx, o.TabName, o.EntityID) + versionInfo, err := o.DB.GetVersionSync(o.Ctx, o.TableName, o.EntityID) if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound { log.ZWarn(o.Ctx, "get version info", err) return nil, err @@ -41,7 +41,7 @@ func (o *VersionSynchronizer[V, R]) getVersionInfo() (*model_struct.LocalVersion } func (o *VersionSynchronizer[V, R]) updateVersionInfo(lvs *model_struct.LocalVersionSync, resp R) error { - lvs.Table = o.TabName + lvs.Table = o.TableName lvs.EntityID = o.EntityID lvs.VersionID, lvs.Version = o.Version(resp) return o.DB.SetVersionSync(o.Ctx, lvs) @@ -73,7 +73,7 @@ func (o *VersionSynchronizer[V, R]) Sync() error { insert := o.Insert(resp) if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { - log.ZDebug(o.Ctx, "no data to sync", "table", o.TabName, "entityID", o.EntityID) + log.ZDebug(o.Ctx, "no data to sync", "table", o.TableName, "entityID", o.EntityID) return nil } @@ -128,7 +128,7 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { insert := o.Insert(resp) _, version := o.Version(resp) if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { - log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TabName, "entityID", o.EntityID) + log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TableName, "entityID", o.EntityID) return nil } if lvs.Version+1 == version { @@ -161,7 +161,7 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { return o.updateVersionInfo(lvs, resp) } else if version <= lvs.Version { log.ZWarn(o.Ctx, "version less than local version", errs.New("version less than local version"), - "table", o.TabName, "entityID", o.EntityID, "version", version, "localVersion", lvs.Version) + "table", o.TableName, "entityID", o.EntityID, "version", version, "localVersion", lvs.Version) return nil } else { // Re-fetch the version number from the server, compare it with the local version number, and fetch the difference once. diff --git a/msgtest/module/friend_manager.go b/msgtest/module/friend_manager.go index ab99b9f7a..675699f76 100644 --- a/msgtest/module/friend_manager.go +++ b/msgtest/module/friend_manager.go @@ -2,6 +2,7 @@ package module import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/protocol/relation" ) type TestFriendManager struct { @@ -9,7 +10,7 @@ type TestFriendManager struct { } func (t *TestFriendManager) ImportFriends(ownerUserID string, friendUserIDs []string) error { - req := &friend.ImportFriendReq{ + req := &relation.ImportFriendReq{ OwnerUserID: ownerUserID, FriendUserIDs: friendUserIDs, } diff --git a/msgtest/pressure_test.go b/msgtest/pressure_test.go index e0b1f229f..d0cf5af6d 100644 --- a/msgtest/pressure_test.go +++ b/msgtest/pressure_test.go @@ -4,12 +4,13 @@ import ( "context" "flag" "fmt" - "github.com/openimsdk/openim-sdk-core/v3/msgtest/module" - "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "sync" "testing" "time" + "github.com/openimsdk/openim-sdk-core/v3/msgtest/module" + "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/log" ) @@ -56,7 +57,7 @@ func init() { InitWithFlag() if err := log.InitFromConfig("sdk.log", "sdk", 4, - true, false, "./chat_log", 2, 24); err != nil { + true, false, "./chat_log", 2, 24, "v1.0.0"); err != nil { panic(err) } } diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go index 8ca01ba40..cb7972ba9 100644 --- a/pkg/datafetcher/datafetcher.go +++ b/pkg/datafetcher/datafetcher.go @@ -2,6 +2,7 @@ package datafetcher import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/utils/datautil" @@ -10,7 +11,7 @@ import ( // DataFetcher is a struct that handles data synchronization type DataFetcher[T any] struct { db db_interface.VersionSyncModel - TabName string + TableName string EntityID string Key func(T) string batchInsert func(ctx context.Context, servers []T) error @@ -25,11 +26,11 @@ type FetchDataFunc[T any] func(ctx context.Context, uids []string) ([]T, error) type FetchFromServerFunc[T any] func(ctx context.Context, uids []string) ([]T, error) // NewDataFetcher creates a new NewDataFetcher -func NewDataFetcher[T any](db db_interface.VersionSyncModel, tabName string, entityID string, key func(T) string, +func NewDataFetcher[T any](db db_interface.VersionSyncModel, tableName string, entityID string, key func(T) string, batchInsert func(ctx context.Context, servers []T) error, fetchFromLocal FetchDataFunc[T], fetchFromServer FetchFromServerFunc[T]) *DataFetcher[T] { return &DataFetcher[T]{ db: db, - TabName: tabName, + TableName: tableName, EntityID: entityID, Key: key, batchInsert: batchInsert, @@ -40,7 +41,7 @@ func NewDataFetcher[T any](db db_interface.VersionSyncModel, tabName string, ent // FetchWithPagination fetches data with pagination and fills missing data from server func (ds *DataFetcher[T]) FetchWithPagination(ctx context.Context, offset, limit int) ([]T, error) { - versionInfo, err := ds.db.GetVersionSync(ctx, ds.TabName, ds.EntityID) + versionInfo, err := ds.db.GetVersionSync(ctx, ds.TableName, ds.EntityID) if err != nil { return nil, err } From 14d05d5cd590676e4185fd6080dcd567cebc076b Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 18:18:04 +0800 Subject: [PATCH 21/69] implement tablename. --- pkg/db/model_struct/data_model_struct.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index b954d96ed..300d00f1c 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -63,6 +63,10 @@ type LocalFriend struct { IsPinned bool `gorm:"column:is_pinned;" json:"isPinned"` } +func (LocalFriend) TableName() string { + return "local_friends" +} + // message FriendRequest{ // string FromUserID = 1; // string ToUserID = 2; From e4d424d97267213f3bc9686a6dbab1f1e273d4df Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 18:19:45 +0800 Subject: [PATCH 22/69] impl tablename method. --- internal/friend/sync2.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index 29e4e84f2..06b26a3b3 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -2,6 +2,8 @@ package friend import ( "context" + + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" ) const ( @@ -47,3 +49,7 @@ func (f *Friend) IncrSyncFriends(ctx context.Context) error { //return opt.Sync() return nil } + +func (f *Friend) friendListTableName() string { + return model_struct.LocalFriend{}.TableName() +} From 8f74c8d8d054611edf2de0ff078500832536ea15 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 18 Jun 2024 18:22:56 +0800 Subject: [PATCH 23/69] refactor: rewrite data Fetch logic. --- internal/friend/sdk.go | 29 ++++++++++++++++++++++++++++- internal/friend/sync.go | 9 +++++++++ internal/group/group.go | 1 + internal/group/sdk.go | 33 +++++++++++++++++++++++++++------ pkg/db/db_interface/databse.go | 2 ++ pkg/db/friend_model.go | 11 +++++++++++ pkg/db/group_member_model.go | 20 ++++++++------------ 7 files changed, 86 insertions(+), 19 deletions(-) diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index f74530d63..4f5b417c7 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -16,8 +16,10 @@ package friend import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" @@ -25,6 +27,7 @@ import ( friend "github.com/openimsdk/protocol/relation" "github.com/openimsdk/protocol/wrapperspb" "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/log" ) @@ -166,10 +169,34 @@ func (f *Friend) GetFriendList(ctx context.Context) ([]*server_api_params.FullUs } func (f *Friend) GetFriendListPage(ctx context.Context, offset, count int32) ([]*server_api_params.FullUserInfo, error) { - localFriendList, err := f.db.GetPageFriendList(ctx, int(offset), int(count)) + datafetcher := datafetcher.NewDataFetcher( + f.db, + f.friendListTableName(), + f.loginUserID, + func(localFriend *model_struct.LocalFriend) string { + return localFriend.FriendUserID + }, + func(ctx context.Context, values []*model_struct.LocalFriend) error { + return f.db.BatchInsertFriend(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + return f.db.GetFriendInfoList(ctx, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + serverFriend, err := f.GetDesignatedFriends(ctx, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerFriendToLocalFriend, serverFriend), nil + }, + ) + + localFriendList, err := datafetcher.FetchWithPagination(ctx, int(offset), int(count)) if err != nil { return nil, err } + + // don't need extra handle. only full pull. localBlackList, err := f.db.GetBlackListDB(ctx) if err != nil { return nil, err diff --git a/internal/friend/sync.go b/internal/friend/sync.go index e70d091bb..ea667d233 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -16,6 +16,7 @@ package friend import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" friend "github.com/openimsdk/protocol/relation" @@ -159,3 +160,11 @@ func (f *Friend) SyncAllBlackList(ctx context.Context) error { log.ZDebug(ctx, "black from local", "data", localData) return f.blockSyncer.Sync(ctx, util.Batch(ServerBlackToLocalBlack, serverData), localData, nil) } + +func (f *Friend) GetDesignatedFriends(ctx context.Context, friendIDs []string) ([]*sdkws.FriendInfo, error) { + resp := &friend.GetDesignatedFriendsResp{} + if err := util.ApiPost(ctx, constant.GetDesignatedFriendsRouter, &friend.GetDesignatedFriendsReq{OwnerUserID: f.loginUserID, FriendUserIDs: friendIDs}, &resp); err != nil { + return nil, err + } + return resp.FriendsInfo, nil +} diff --git a/internal/group/group.go b/internal/group/group.go index 3d33bfac9..512701914 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -16,6 +16,7 @@ package group import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 05e0c32c9..72706e35d 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -16,9 +16,10 @@ package group import ( "context" + "time" + "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" "github.com/openimsdk/tools/utils/datautil" - "time" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -176,8 +177,29 @@ func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.S return g.SyncGroupMembers(ctx, groupMemberInfo.GroupID, groupMemberInfo.UserID) } -func (g *Group) GetJoinedGroupList(ctx context.Context) ([]*model_struct.LocalGroup, error) { - return g.db.GetJoinedGroupListDB(ctx) +func (g *Group) GetJoinedGroupList(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, error) { + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupTableName(), + g.loginUserID, + func(localGroup *model_struct.LocalGroup) string { + return localGroup.GroupID + }, + func(ctx context.Context, values []*model_struct.LocalGroup) error { + return g.db.BatchInsertGroup(ctx, values) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + return g.db.GetGroups(ctx, groupIDs) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + serverGroupInfo, err := g.getGroupsInfoFromSvr(ctx, groupIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupToLocalGroup, serverGroupInfo), nil + }, + ) + return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) } func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { @@ -261,9 +283,8 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, func(ctx context.Context, values []*model_struct.LocalGroupMember) error { return g.db.BatchInsertGroupMember(ctx, values) }, - func(ctx context.Context, uids []string) ([]*model_struct.LocalGroupMember, error) { - //todo GetGroupMemberListSplit change to - return g.db.GetGroupMemberListSplit(ctx, groupID, filter, int(offset), int(count)) + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListByUserIDs(ctx, groupID, filter, userIDs) }, func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index b64d3af27..90a780551 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -234,6 +234,8 @@ type FriendModel interface { UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error) GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error) + BatchInsertFriend(ctx context.Context, friendList []*model_struct.LocalFriend) error + SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error) GetFriendInfoByFriendUserID(ctx context.Context, FriendUserID string) (*model_struct.LocalFriend, error) GetFriendInfoList(ctx context.Context, friendUserIDList []string) ([]*model_struct.LocalFriend, error) diff --git a/pkg/db/friend_model.go b/pkg/db/friend_model.go index ba2030f8f..65b3a0bae 100644 --- a/pkg/db/friend_model.go +++ b/pkg/db/friend_model.go @@ -21,8 +21,10 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertFriend(ctx context.Context, friend *model_struct.LocalFriend) error { @@ -79,6 +81,15 @@ func (d *DataBase) GetPageFriendList(ctx context.Context, offset, count int) ([] return friendList, err } +func (d *DataBase) BatchInsertFriend(ctx context.Context, friendList []*model_struct.LocalFriend) error { + d.friendMtx.Lock() + defer d.friendMtx.Unlock() + if friendList == nil { + return errs.New("nil").Wrap() + } + return errs.WrapMsg(d.conn.WithContext(ctx).Create(friendList).Error, "BatchInsertFriendList failed") +} + func (d *DataBase) SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 141c1dbc5..218056c3b 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -92,7 +92,7 @@ func (d *DataBase) GetGroupMemberListByGroupID(ctx context.Context, groupID stri func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember var err error switch filter { case constant.GroupFilterAll: @@ -100,22 +100,18 @@ func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID stri case constant.GroupFilterOwner: err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOwner, userIDs).Find(&groupMemberList).Error case constant.GroupFilterAdmin: - err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupAdmin, userIDs).Order("join_time ASC").Find(&groupMemberList).Error + err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupAdmin, userIDs).Find(&groupMemberList).Error case constant.GroupFilterOrdinaryUsers: - err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOrdinaryUsers, userIDs).Order("join_time ASC").Find(&groupMemberList).Error + err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOrdinaryUsers, userIDs).Find(&groupMemberList).Error case constant.GroupFilterAdminAndOrdinaryUsers: - err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupAdmin, constant.GroupOrdinaryUsers, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error + err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupAdmin, constant.GroupOrdinaryUsers, userIDs).Find(&groupMemberList).Error case constant.GroupFilterOwnerAndAdmin: - err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupOwner, constant.GroupAdmin, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error + err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupOwner, constant.GroupAdmin, userIDs).Find(&groupMemberList).Error default: return nil, errs.New("filter args failed.", "filter", filter).Wrap() } - var transfer []*model_struct.LocalGroupMember - for _, member := range groupMemberList { - memberCopy := member - transfer = append(transfer, &memberCopy) - } - return transfer, errs.Wrap(err) + + return groupMemberList, errs.Wrap(err) } @@ -230,7 +226,7 @@ func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList [ if groupMemberList == nil { return errors.New("nil") } - return utils.Wrap(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertMessageList failed") } func (d *DataBase) DeleteGroupMember(ctx context.Context, groupID, userID string) error { From c1434a8cb1d8b4e321c5bad5243568485496455b Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Wed, 19 Jun 2024 17:06:04 +0800 Subject: [PATCH 24/69] refactor: refactor file structure. --- open_im_sdk/group.go | 75 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/open_im_sdk/group.go b/open_im_sdk/group.go index 3d614ce19..41d3ae680 100644 --- a/open_im_sdk/group.go +++ b/open_im_sdk/group.go @@ -36,16 +36,35 @@ func DismissGroup(callback open_im_sdk_callback.Base, operationID string, groupI call(callback, operationID, UserForSDK.Group().DismissGroup, groupID) } +func SetGroupMemberRoleLevel(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, roleLevel int) { + call(callback, operationID, UserForSDK.Group().SetGroupMemberRoleLevel, groupID, userID, roleLevel) +} + +func SetGroupVerification(callback open_im_sdk_callback.Base, operationID string, groupID string, verification int32) { + call(callback, operationID, UserForSDK.Group().SetGroupVerification, groupID, verification) +} +func SetGroupApplyMemberFriend(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { + call(callback, operationID, UserForSDK.Group().SetGroupApplyMemberFriend, groupID, rule) +} + func ChangeGroupMute(callback open_im_sdk_callback.Base, operationID string, groupID string, isMute bool) { call(callback, operationID, UserForSDK.Group().ChangeGroupMute, groupID, isMute) } -func ChangeGroupMemberMute(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, mutedSeconds int) { - call(callback, operationID, UserForSDK.Group().ChangeGroupMemberMute, groupID, userID, mutedSeconds) +func SetGroupInfo(callback open_im_sdk_callback.Base, operationID string, groupInfo string) { + call(callback, operationID, UserForSDK.Group().SetGroupInfo, groupInfo) } -func SetGroupMemberRoleLevel(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, roleLevel int) { - call(callback, operationID, UserForSDK.Group().SetGroupMemberRoleLevel, groupID, userID, roleLevel) +func KickGroupMember(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { + call(callback, operationID, UserForSDK.Group().KickGroupMember, groupID, reason, userIDList) +} + +func TransferGroupOwner(callback open_im_sdk_callback.Base, operationID string, groupID string, newOwnerUserID string) { + call(callback, operationID, UserForSDK.Group().TransferGroupOwner, groupID, newOwnerUserID) +} + +func ChangeGroupMemberMute(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, mutedSeconds int) { + call(callback, operationID, UserForSDK.Group().ChangeGroupMemberMute, groupID, userID, mutedSeconds) } func SetGroupMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupMemberInfo string) { @@ -64,26 +83,10 @@ func SearchGroups(callback open_im_sdk_callback.Base, operationID string, search call(callback, operationID, UserForSDK.Group().SearchGroups, searchParam) } -func SetGroupInfo(callback open_im_sdk_callback.Base, operationID string, groupInfo string) { - call(callback, operationID, UserForSDK.Group().SetGroupInfo, groupInfo) -} - -func SetGroupVerification(callback open_im_sdk_callback.Base, operationID string, groupID string, verification int32) { - call(callback, operationID, UserForSDK.Group().SetGroupVerification, groupID, verification) -} - func SetGroupLookMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { call(callback, operationID, UserForSDK.Group().SetGroupLookMemberInfo, groupID, rule) } -func SetGroupApplyMemberFriend(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { - call(callback, operationID, UserForSDK.Group().SetGroupApplyMemberFriend, groupID, rule) -} - -func GetGroupMemberList(callback open_im_sdk_callback.Base, operationID string, groupID string, filter int32, offset int32, count int32) { - call(callback, operationID, UserForSDK.Group().GetGroupMemberList, groupID, filter, offset, count) -} - func GetGroupMemberOwnerAndAdmin(callback open_im_sdk_callback.Base, operationID string, groupID string) { call(callback, operationID, UserForSDK.Group().GetGroupMemberOwnerAndAdmin, groupID) } @@ -96,16 +99,8 @@ func GetSpecifiedGroupMembersInfo(callback open_im_sdk_callback.Base, operationI call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupMembersInfo, groupID, userIDList) } -func KickGroupMember(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { - call(callback, operationID, UserForSDK.Group().KickGroupMember, groupID, reason, userIDList) -} - -func TransferGroupOwner(callback open_im_sdk_callback.Base, operationID string, groupID string, newOwnerUserID string) { - call(callback, operationID, UserForSDK.Group().TransferGroupOwner, groupID, newOwnerUserID) -} - -func InviteUserToGroup(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { - call(callback, operationID, UserForSDK.Group().InviteUserToGroup, groupID, reason, userIDList) +func GetGroupMemberList(callback open_im_sdk_callback.Base, operationID string, groupID string, filter int32, offset int32, count int32) { + call(callback, operationID, UserForSDK.Group().GetGroupMemberList, groupID, filter, offset, count) } func GetGroupApplicationListAsRecipient(callback open_im_sdk_callback.Base, operationID string) { @@ -116,6 +111,18 @@ func GetGroupApplicationListAsApplicant(callback open_im_sdk_callback.Base, oper call(callback, operationID, UserForSDK.Group().GetGroupApplicationListAsApplicant) } +func SearchGroupMembers(callback open_im_sdk_callback.Base, operationID string, searchParam string) { + call(callback, operationID, UserForSDK.Group().SearchGroupMembers, searchParam) +} + +func IsJoinGroup(callback open_im_sdk_callback.Base, operationID string, groupID string) { + call(callback, operationID, UserForSDK.Group().IsJoinGroup, groupID) +} + +func InviteUserToGroup(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { + call(callback, operationID, UserForSDK.Group().InviteUserToGroup, groupID, reason, userIDList) +} + func AcceptGroupApplication(callback open_im_sdk_callback.Base, operationID string, groupID string, fromUserID string, handleMsg string) { call(callback, operationID, UserForSDK.Group().AcceptGroupApplication, groupID, fromUserID, handleMsg) } @@ -127,11 +134,3 @@ func RefuseGroupApplication(callback open_im_sdk_callback.Base, operationID stri func SetGroupMemberNickname(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, groupMemberNickname string) { call(callback, operationID, UserForSDK.Group().SetGroupMemberNickname, groupID, userID, groupMemberNickname) } - -func SearchGroupMembers(callback open_im_sdk_callback.Base, operationID string, searchParam string) { - call(callback, operationID, UserForSDK.Group().SearchGroupMembers, searchParam) -} - -func IsJoinGroup(callback open_im_sdk_callback.Base, operationID string, groupID string) { - call(callback, operationID, UserForSDK.Group().IsJoinGroup, groupID) -} From b8bf09eb085a59441b08475fd055cbe638253102 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Wed, 19 Jun 2024 17:48:53 +0800 Subject: [PATCH 25/69] refactor: refactoring group sdk structure. --- internal/group/sdk.go | 199 +++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 108 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 9f5c4a6e6..df13f77e4 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -18,15 +18,15 @@ import ( "context" "time" - "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" "github.com/openimsdk/tools/utils/datautil" + "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" - "github.com/openimsdk/tools/log" "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" @@ -78,6 +78,18 @@ func (g *Group) DismissGroup(ctx context.Context, groupID string) error { return nil } +func (g *Group) SetGroupApplyMemberFriend(ctx context.Context, groupID string, rule int32) error { + return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, ApplyMemberFriend: wrapperspb.Int32(rule)}) +} + +func (g *Group) SetGroupLookMemberInfo(ctx context.Context, groupID string, rule int32) error { + return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, LookMemberInfo: wrapperspb.Int32(rule)}) +} + +func (g *Group) SetGroupVerification(ctx context.Context, groupID string, verification int32) error { + return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, NeedVerification: wrapperspb.Int32(verification)}) +} + func (g *Group) ChangeGroupMute(ctx context.Context, groupID string, isMute bool) (err error) { if isMute { err = util.ApiPost(ctx, constant.MuteGroupRouter, &group.MuteGroupReq{GroupID: groupID}, nil) @@ -105,12 +117,31 @@ func (g *Group) ChangeGroupMemberMute(ctx context.Context, groupID, userID strin return nil } -func (g *Group) SetGroupMemberRoleLevel(ctx context.Context, groupID, userID string, roleLevel int) error { - return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, RoleLevel: wrapperspb.Int32(int32(roleLevel))}) +func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID string) error { + if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { + return err + } + if err := g.IncrSyncJoinGroup(ctx); err != nil { + return err + } + if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { + return err + } + return nil } -func (g *Group) SetGroupMemberNickname(ctx context.Context, groupID, userID string, groupMemberNickname string) error { - return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, Nickname: wrapperspb.String(groupMemberNickname)}) +func (g *Group) KickGroupMember(ctx context.Context, groupID string, reason string, userIDList []string) error { + if err := util.ApiPost(ctx, constant.KickGroupMemberRouter, &group.KickGroupMemberReq{GroupID: groupID, KickedUserIDs: userIDList, Reason: reason}, nil); err != nil { + return err + } + return g.IncrSyncGroupMember(ctx, groupID) +} + +func (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdkws.GroupInfoForSet) error { + if err := util.ApiPost(ctx, constant.SetGroupInfoRouter, &group.SetGroupInfoReq{GroupInfoForSet: groupInfo}, nil); err != nil { + return err + } + return g.IncrSyncJoinGroup(ctx) } func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.SetGroupMemberInfo) error { @@ -120,6 +151,14 @@ func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.S return g.IncrSyncGroupMember(ctx, groupMemberInfo.GroupID) } +func (g *Group) SetGroupMemberRoleLevel(ctx context.Context, groupID, userID string, roleLevel int) error { + return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, RoleLevel: wrapperspb.Int32(int32(roleLevel))}) +} + +func (g *Group) SetGroupMemberNickname(ctx context.Context, groupID, userID string, groupMemberNickname string) error { + return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, Nickname: wrapperspb.String(groupMemberNickname)}) +} + func (g *Group) GetJoinedGroupList(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, @@ -146,31 +185,28 @@ func (g *Group) GetJoinedGroupList(ctx context.Context, offset, count int32) ([] } func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { - groupList, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return nil, err - } - groupIDMap := datautil.SliceSet(groupIDs) - res := make([]*model_struct.LocalGroup, 0, len(groupIDs)) - for i, v := range groupList { - if _, ok := groupIDMap[v.GroupID]; ok { - delete(groupIDMap, v.GroupID) - res = append(res, groupList[i]) - } - } - if len(groupIDMap) > 0 { - groups, err := util.CallApi[group.GetGroupsInfoResp](ctx, constant.GetGroupsInfoRouter, &group.GetGroupsInfoReq{GroupIDs: datautil.Keys(groupIDMap)}) - if err != nil { - log.ZError(ctx, "Call GetGroupsInfoRouter", err) - } - if groups != nil && len(groups.GroupInfos) > 0 { - for i := range groups.GroupInfos { - groups.GroupInfos[i].MemberCount = 0 + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupTableName(), + g.loginUserID, + func(localGroup *model_struct.LocalGroup) string { + return localGroup.GroupID + }, + func(ctx context.Context, values []*model_struct.LocalGroup) error { + return g.db.BatchInsertGroup(ctx, values) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + return g.db.GetGroups(ctx, groupIDs) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + serverGroupInfo, err := g.getGroupsInfoFromSvr(ctx, groupIDs) + if err != nil { + return nil, err } - res = append(res, util.Batch(ServerGroupToLocalGroup, groups.GroupInfos)...) - } - } - return res, nil + return datautil.Batch(ServerGroupToLocalGroup, serverGroupInfo), nil + }, + ) + return dataFetcher.FetchMissingAndFillLocal(ctx, groupIDs) } func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.SearchGroupsParam) ([]*model_struct.LocalGroup, error) { @@ -184,35 +220,19 @@ func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.Sear return groups, nil } -// funcation (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdk_params_callback.SetGroupInfoParam, groupID string) error { -// return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{ -// GroupID: groupID, -// GroupName: groupInfo.GroupName, -// Notification: groupInfo.Notification, -// Introduction: groupInfo.Introduction, -// FaceURL: groupInfo.FaceURL, -// Ex: groupInfo.Ex, -// NeedVerification: wrapperspb.Int32Ptr(groupInfo.NeedVerification), -// }) -// } - -func (g *Group) SetGroupVerification(ctx context.Context, groupID string, verification int32) error { - return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, NeedVerification: wrapperspb.Int32(verification)}) -} - -func (g *Group) SetGroupLookMemberInfo(ctx context.Context, groupID string, rule int32) error { - return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, LookMemberInfo: wrapperspb.Int32(rule)}) +func (g *Group) GetGroupMemberOwnerAndAdmin(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberOwnerAndAdminDB(ctx, groupID) } -func (g *Group) SetGroupApplyMemberFriend(ctx context.Context, groupID string, rule int32) error { - return g.SetGroupInfo(ctx, &sdkws.GroupInfoForSet{GroupID: groupID, ApplyMemberFriend: wrapperspb.Int32(rule)}) +func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID string, offset, count int32, joinTimeBegin, joinTimeEnd int64, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + if joinTimeEnd == 0 { + joinTimeEnd = time.Now().UnixMilli() + } + return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) } -func (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdkws.GroupInfoForSet) error { - if err := util.ApiPost(ctx, constant.SetGroupInfoRouter, &group.SetGroupInfoReq{GroupInfoForSet: groupInfo}, nil); err != nil { - return err - } - return g.IncrSyncJoinGroup(ctx) +func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { @@ -238,44 +258,32 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, }, ) return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) - -} - -func (g *Group) GetGroupMemberOwnerAndAdmin(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupMemberOwnerAndAdminDB(ctx, groupID) } -func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID string, offset, count int32, joinTimeBegin, joinTimeEnd int64, userIDs []string) ([]*model_struct.LocalGroupMember, error) { - if joinTimeEnd == 0 { - joinTimeEnd = time.Now().UnixMilli() - } - return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) +func (g *Group) GetGroupApplicationListAsRecipient(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { + return g.db.GetAdminGroupApplication(ctx) } -func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) +func (g *Group) GetGroupApplicationListAsApplicant(ctx context.Context) ([]*model_struct.LocalGroupRequest, error) { + return g.db.GetSendGroupApplication(ctx) } -func (g *Group) KickGroupMember(ctx context.Context, groupID string, reason string, userIDList []string) error { - if err := util.ApiPost(ctx, constant.KickGroupMemberRouter, &group.KickGroupMemberReq{GroupID: groupID, KickedUserIDs: userIDList, Reason: reason}, nil); err != nil { - return err - } - return g.IncrSyncGroupMember(ctx, groupID) +func (g *Group) SearchGroupMembers(ctx context.Context, searchParam *sdk_params_callback.SearchGroupMembersParam) ([]*model_struct.LocalGroupMember, error) { + return g.db.SearchGroupMembersDB(ctx, searchParam.KeywordList[0], searchParam.GroupID, searchParam.IsSearchMemberNickname, searchParam.IsSearchUserID, searchParam.Offset, searchParam.Count) } -func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID string) error { - if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { - return err - } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err +func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { + groupList, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return false, err } - if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { - return err + for _, localGroup := range groupList { + if localGroup.GroupID == groupID { + return true, nil + } } - return nil + return false, nil } - func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, userIDList []string) error { if err := util.ApiPost(ctx, constant.InviteUserToGroupRouter, &group.InviteUserToGroupReq{GroupID: groupID, Reason: reason, InvitedUserIDs: userIDList}, nil); err != nil { return err @@ -289,14 +297,6 @@ func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, u return nil } -func (g *Group) GetGroupApplicationListAsRecipient(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { - return g.db.GetAdminGroupApplication(ctx) -} - -func (g *Group) GetGroupApplicationListAsApplicant(ctx context.Context) ([]*model_struct.LocalGroupRequest, error) { - return g.db.GetSendGroupApplication(ctx) -} - func (g *Group) AcceptGroupApplication(ctx context.Context, groupID, fromUserID, handleMsg string) error { return g.HandlerGroupApplication(ctx, &group.GroupApplicationResponseReq{GroupID: groupID, FromUserID: fromUserID, HandledMsg: handleMsg, HandleResult: constant.GroupResponseAgree}) } @@ -313,23 +313,6 @@ func (g *Group) HandlerGroupApplication(ctx context.Context, req *group.GroupApp return nil } -func (g *Group) SearchGroupMembers(ctx context.Context, searchParam *sdk_params_callback.SearchGroupMembersParam) ([]*model_struct.LocalGroupMember, error) { - return g.db.SearchGroupMembersDB(ctx, searchParam.KeywordList[0], searchParam.GroupID, searchParam.IsSearchMemberNickname, searchParam.IsSearchUserID, searchParam.Offset, searchParam.Count) -} - -func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { - groupList, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return false, err - } - for _, localGroup := range groupList { - if localGroup.GroupID == groupID { - return true, nil - } - } - return false, nil -} - //func (g *Group) SearchGroupMembersV2(ctx context.Context, req *group.SearchGroupMemberReq) ([]*model_struct.LocalGroupMember, error) { // if err := req.Check(); err != nil { // return nil, err @@ -362,6 +345,6 @@ func (g *Group) pbGroupMemberToLocal(pb *sdkws.GroupMemberFullInfo) *model_struc MuteEndTime: pb.MuteEndTime, OperatorUserID: pb.OperatorUserID, Ex: pb.Ex, - //AttachedInfo: pb.AttachedInfo, + // AttachedInfo: pb.AttachedInfo, } } From b041eb3dc2595cd5c05ea4de3f5beb302fe8863f Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:25:04 +0800 Subject: [PATCH 26/69] feat: friend full sync and incr sync. --- go.mod | 4 +- go.sum | 8 +- internal/conversation_msg/conversation.go | 5 +- .../conversation_notification.go | 192 +++++----- internal/friend/friend.go | 95 +++-- internal/friend/sync.go | 20 +- internal/friend/sync2.go | 93 +++-- internal/group/group.go | 6 +- internal/group/notification.go | 344 +++--------------- internal/group/sdk.go | 24 +- internal/group/sync.go | 12 +- internal/group/sync2.go | 84 ++++- internal/incrversion/option.go | 71 +++- internal/user/sync.go | 3 +- internal/user/user.go | 3 +- internal/util/conversion.go | 26 -- internal/util/post.go | 8 +- pkg/common/trigger_channel.go | 12 - pkg/constant/server_api_router.go | 5 +- pkg/db/db_interface/databse.go | 1 + pkg/db/friend_model.go | 7 + testv2/sync2_test.go | 2 +- 22 files changed, 451 insertions(+), 574 deletions(-) delete mode 100644 internal/util/conversion.go diff --git a/go.mod b/go.mod index 0dbe44b37..2b75a4296 100644 --- a/go.mod +++ b/go.mod @@ -17,8 +17,8 @@ require golang.org/x/net v0.22.0 require ( github.com/google/go-cmp v0.6.0 - github.com/openimsdk/protocol v0.0.69-alpha.9 - github.com/openimsdk/tools v0.0.49-alpha.9 + github.com/openimsdk/protocol v0.0.69-alpha.16 + github.com/openimsdk/tools v0.0.49-alpha.12 github.com/patrickmn/go-cache v2.1.0+incompatible go.etcd.io/etcd/api/v3 v3.5.13 golang.org/x/image v0.15.0 diff --git a/go.sum b/go.sum index cb4145599..d0c5e2fd4 100644 --- a/go.sum +++ b/go.sum @@ -27,10 +27,10 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/openimsdk/protocol v0.0.69-alpha.9 h1:Mh1upsxwhWs1y65cfIN2XuRsiKEk4MfpYfA9XrvtX24= -github.com/openimsdk/protocol v0.0.69-alpha.9/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= -github.com/openimsdk/tools v0.0.49-alpha.9 h1:yoa3GS6t0d1mRv/S86niFBGDgSjy2EWWwBI5NAH1Kgk= -github.com/openimsdk/tools v0.0.49-alpha.9/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= +github.com/openimsdk/protocol v0.0.69-alpha.16 h1:ciSqm2rjBdpScpkQm3wPjAFv0YbIRp8MITRkDZWVv6c= +github.com/openimsdk/protocol v0.0.69-alpha.16/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= +github.com/openimsdk/tools v0.0.49-alpha.12 h1:vsr63W1kHW1dEw9yelMhmr72WmsrjKfs2vXww3upfWI= +github.com/openimsdk/tools v0.0.49-alpha.12/go.mod h1:g7mkHXYUPi0/8aAX8VPMHpnb3hqdV69Jph+bXOGvvNM= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/internal/conversation_msg/conversation.go b/internal/conversation_msg/conversation.go index 8fbbd1d20..bbd4da643 100644 --- a/internal/conversation_msg/conversation.go +++ b/internal/conversation_msg/conversation.go @@ -27,6 +27,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/utils/datautil" "sort" "strings" "time" @@ -58,7 +59,7 @@ func (c *Conversation) getServerConversationList(ctx context.Context) ([]*model_ if err != nil { return nil, err } - return util.Batch(ServerConversationToLocal, resp.Conversations), nil + return datautil.Batch(ServerConversationToLocal, resp.Conversations), nil } func (c *Conversation) getServerConversationsByIDs(ctx context.Context, conversations []string) ([]*model_struct.LocalConversation, error) { @@ -66,7 +67,7 @@ func (c *Conversation) getServerConversationsByIDs(ctx context.Context, conversa if err != nil { return nil, err } - return util.Batch(ServerConversationToLocal, resp.Conversations), nil + return datautil.Batch(ServerConversationToLocal, resp.Conversations), nil } func (c *Conversation) getServerHasReadAndMaxSeqs(ctx context.Context, conversationIDs ...string) (map[string]*msg.Seqs, error) { diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 925142f9c..82039376a 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -33,23 +33,115 @@ func (c *Conversation) Work(c2v common.Cmd2Value) { log.ZDebug(c2v.Ctx, "NotificationCmd start", "cmd", c2v.Cmd, "value", c2v.Value) defer log.ZDebug(c2v.Ctx, "NotificationCmd end", "cmd", c2v.Cmd, "value", c2v.Value) switch c2v.Cmd { - case constant.CmdDeleteConversation: - c.doDeleteConversation(c2v) case constant.CmdNewMsgCome: c.doMsgNew(c2v) case constant.CmdSuperGroupMsgCome: - // c.doSuperGroupMsgNew(c2v) case constant.CmdUpdateConversation: c.doUpdateConversation(c2v) case constant.CmdUpdateMessage: c.doUpdateMessage(c2v) case constant.CmSyncReactionExtensions: - // c.doSyncReactionExtensions(c2v) case constant.CmdNotification: c.doNotificationNew(c2v) } } +func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { + ctx := c2v.Ctx + allMsg := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).Msgs + syncFlag := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).SyncFlag + switch syncFlag { + case constant.MsgSyncBegin: + c.startTime = time.Now() + c.ConversationListener().OnSyncServerStart() + if err := c.SyncAllConversationHashReadSeqs(ctx); err != nil { + log.ZError(ctx, "SyncConversationHashReadSeqs err", err) + } + //clear SubscriptionStatusMap + c.user.OnlineStatusCache.DeleteAll() + //for _, syncFunc := range []func(c context.Context) error{ + // c.user.SyncLoginUserInfo, + // c.friend.SyncAllBlackList, c.friend.SyncAllFriendList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, + // c.group.SyncAllJoinedGroupsAndMembers, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, + //} { + // go func(syncFunc func(c context.Context) error) { + // _ = syncFunc(ctx) + // }(syncFunc) + //} + c.group.SyncAllJoinedGroupsAndMembers2(ctx) + err := c.friend.SyncAllFriendList(ctx) + if err != nil { + log.ZError(ctx, "SyncAllFriendList err", err) + } + case constant.MsgSyncFailed: + c.ConversationListener().OnSyncServerFailed() + case constant.MsgSyncEnd: + log.ZDebug(ctx, "MsgSyncEnd", "time", time.Since(c.startTime).Milliseconds()) + defer c.ConversationListener().OnSyncServerFinish() + go c.SyncAllConversations(ctx) + } + + for conversationID, msgs := range allMsg { + log.ZDebug(ctx, "notification handling", "conversationID", conversationID, "msgs", msgs) + if len(msgs.Msgs) != 0 { + lastMsg := msgs.Msgs[len(msgs.Msgs)-1] + log.ZDebug(ctx, "SetNotificationSeq", "conversationID", conversationID, "seq", lastMsg.Seq) + if lastMsg.Seq != 0 { + if err := c.db.SetNotificationSeq(ctx, conversationID, lastMsg.Seq); err != nil { + log.ZError(ctx, "SetNotificationSeq err", err, "conversationID", conversationID, "lastMsg", lastMsg) + } + } + } + for _, v := range msgs.Msgs { + switch { + case v.ContentType == constant.ConversationChangeNotification: + c.DoConversationChangedNotification(ctx, v) + case v.ContentType == constant.ConversationPrivateChatNotification: + c.DoConversationIsPrivateChangedNotification(ctx, v) + case v.ContentType == constant.ConversationUnreadNotification: + var tips sdkws.ConversationHasReadTips + _ = json.Unmarshal(v.Content, &tips) + c.doUpdateConversation(common.Cmd2Value{Value: common.UpdateConNode{ConID: tips.ConversationID, Action: constant.UnreadCountSetZero}}) + c.db.DeleteConversationUnreadMessageList(ctx, tips.ConversationID, tips.UnreadCountTime) + c.doUpdateConversation(common.Cmd2Value{Value: common.UpdateConNode{Action: constant.ConChange, Args: []string{tips.ConversationID}}}) + continue + case v.ContentType == constant.BusinessNotification: + c.business.DoNotification(ctx, v) + continue + case v.ContentType == constant.RevokeNotification: + c.doRevokeMsg(ctx, v) + case v.ContentType == constant.ClearConversationNotification: + c.doClearConversations(ctx, v) + case v.ContentType == constant.DeleteMsgsNotification: + c.doDeleteMsgs(ctx, v) + case v.ContentType == constant.HasReadReceipt: + c.doReadDrawing(ctx, v) + } + + switch v.SessionType { + case constant.SingleChatType: + if v.ContentType > constant.FriendNotificationBegin && v.ContentType < constant.FriendNotificationEnd { + c.friend.DoNotification(ctx, v) + } else if v.ContentType > constant.UserNotificationBegin && v.ContentType < constant.UserNotificationEnd { + c.user.DoNotification(ctx, v) + } else if datautil.Contain(v.ContentType, constant.GroupApplicationRejectedNotification, constant.GroupApplicationAcceptedNotification, constant.JoinGroupApplicationNotification) { + c.group.DoNotification(ctx, v) + } else if v.ContentType > constant.SignalingNotificationBegin && v.ContentType < constant.SignalingNotificationEnd { + + continue + } + case constant.GroupChatType, constant.SuperGroupChatType: + if v.ContentType > constant.GroupNotificationBegin && v.ContentType < constant.GroupNotificationEnd { + c.group.DoNotification(ctx, v) + } else if v.ContentType > constant.SignalingNotificationBegin && v.ContentType < constant.SignalingNotificationEnd { + continue + } + } + } + } + +} + func (c *Conversation) doDeleteConversation(c2v common.Cmd2Value) { node := c2v.Value.(common.DeleteConNode) ctx := c2v.Ctx @@ -606,95 +698,3 @@ func (c *Conversation) DoConversationIsPrivateChangedNotification(ctx context.Co c.SyncConversations(ctx, []string{tips.ConversationID}) } - -func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { - ctx := c2v.Ctx - allMsg := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).Msgs - syncFlag := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).SyncFlag - switch syncFlag { - case constant.MsgSyncBegin: - c.startTime = time.Now() - c.ConversationListener().OnSyncServerStart() - if err := c.SyncAllConversationHashReadSeqs(ctx); err != nil { - log.ZError(ctx, "SyncConversationHashReadSeqs err", err) - } - //clear SubscriptionStatusMap - c.user.OnlineStatusCache.DeleteAll() - //for _, syncFunc := range []func(c context.Context) error{ - // c.user.SyncLoginUserInfo, - // c.friend.SyncAllBlackList, c.friend.SyncAllFriendList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, - // c.group.SyncAllJoinedGroupsAndMembers, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, - //} { - // go func(syncFunc func(c context.Context) error) { - // _ = syncFunc(ctx) - // }(syncFunc) - //} - c.group.SyncAllJoinedGroupsAndMembers2(ctx) - case constant.MsgSyncFailed: - c.ConversationListener().OnSyncServerFailed() - case constant.MsgSyncEnd: - log.ZDebug(ctx, "MsgSyncEnd", "time", time.Since(c.startTime).Milliseconds()) - defer c.ConversationListener().OnSyncServerFinish() - go c.SyncAllConversations(ctx) - } - - for conversationID, msgs := range allMsg { - log.ZDebug(ctx, "notification handling", "conversationID", conversationID, "msgs", msgs) - if len(msgs.Msgs) != 0 { - lastMsg := msgs.Msgs[len(msgs.Msgs)-1] - log.ZDebug(ctx, "SetNotificationSeq", "conversationID", conversationID, "seq", lastMsg.Seq) - if lastMsg.Seq != 0 { - if err := c.db.SetNotificationSeq(ctx, conversationID, lastMsg.Seq); err != nil { - log.ZError(ctx, "SetNotificationSeq err", err, "conversationID", conversationID, "lastMsg", lastMsg) - } - } - } - for _, v := range msgs.Msgs { - switch { - case v.ContentType == constant.ConversationChangeNotification: - c.DoConversationChangedNotification(ctx, v) - case v.ContentType == constant.ConversationPrivateChatNotification: - c.DoConversationIsPrivateChangedNotification(ctx, v) - case v.ContentType == constant.ConversationUnreadNotification: - var tips sdkws.ConversationHasReadTips - _ = json.Unmarshal(v.Content, &tips) - c.doUpdateConversation(common.Cmd2Value{Value: common.UpdateConNode{ConID: tips.ConversationID, Action: constant.UnreadCountSetZero}}) - c.db.DeleteConversationUnreadMessageList(ctx, tips.ConversationID, tips.UnreadCountTime) - c.doUpdateConversation(common.Cmd2Value{Value: common.UpdateConNode{Action: constant.ConChange, Args: []string{tips.ConversationID}}}) - continue - case v.ContentType == constant.BusinessNotification: - c.business.DoNotification(ctx, v) - continue - case v.ContentType == constant.RevokeNotification: - c.doRevokeMsg(ctx, v) - case v.ContentType == constant.ClearConversationNotification: - c.doClearConversations(ctx, v) - case v.ContentType == constant.DeleteMsgsNotification: - c.doDeleteMsgs(ctx, v) - case v.ContentType == constant.HasReadReceipt: - c.doReadDrawing(ctx, v) - } - - switch v.SessionType { - case constant.SingleChatType: - if v.ContentType > constant.FriendNotificationBegin && v.ContentType < constant.FriendNotificationEnd { - c.friend.DoNotification(ctx, v) - } else if v.ContentType > constant.UserNotificationBegin && v.ContentType < constant.UserNotificationEnd { - c.user.DoNotification(ctx, v) - } else if datautil.Contain(v.ContentType, constant.GroupApplicationRejectedNotification, constant.GroupApplicationAcceptedNotification, constant.JoinGroupApplicationNotification) { - c.group.DoNotification(ctx, v) - } else if v.ContentType > constant.SignalingNotificationBegin && v.ContentType < constant.SignalingNotificationEnd { - - continue - } - case constant.GroupChatType, constant.SuperGroupChatType: - if v.ContentType > constant.GroupNotificationBegin && v.ContentType < constant.GroupNotificationEnd { - c.group.DoNotification(ctx, v) - } else if v.ContentType > constant.SignalingNotificationBegin && v.ContentType < constant.SignalingNotificationEnd { - continue - } - } - } - } - -} diff --git a/internal/friend/friend.go b/internal/friend/friend.go index 3a8df9f32..5835f6996 100644 --- a/internal/friend/friend.go +++ b/internal/friend/friend.go @@ -23,8 +23,11 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/openim-sdk-core/v3/pkg/page" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + friend "github.com/openimsdk/protocol/relation" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" @@ -41,7 +44,7 @@ type Friend struct { loginUserID string db db_interface.DataBase user *user.User - friendSyncer *syncer.Syncer[*model_struct.LocalFriend, syncer.NoResp, [2]string] + friendSyncer *syncer.Syncer[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string] blockSyncer *syncer.Syncer[*model_struct.LocalBlack, syncer.NoResp, [2]string] requestRecvSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] requestSendSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] @@ -50,37 +53,71 @@ type Friend struct { } func (f *Friend) initSyncer() { - f.friendSyncer = syncer.New[*model_struct.LocalFriend, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error { - return f.db.InsertFriend(ctx, value) - }, func(ctx context.Context, value *model_struct.LocalFriend) error { - return f.db.DeleteFriendDB(ctx, value.FriendUserID) - }, func(ctx context.Context, server *model_struct.LocalFriend, local *model_struct.LocalFriend) error { - return f.db.UpdateFriend(ctx, server) - - }, func(value *model_struct.LocalFriend) [2]string { - return [...]string{value.OwnerUserID, value.FriendUserID} - }, nil, func(ctx context.Context, state int, server, local *model_struct.LocalFriend) error { - switch state { - case syncer.Insert: - f.friendListener.OnFriendAdded(*server) - case syncer.Delete: - log.ZDebug(ctx, "syncer OnFriendDeleted", "local", local) - f.friendListener.OnFriendDeleted(*local) - case syncer.Update: - f.friendListener.OnFriendInfoChanged(*server) - if local.Nickname != server.Nickname || local.FaceURL != server.FaceURL || local.Remark != server.Remark { - if server.Remark != "" { - server.Nickname = server.Remark + f.friendSyncer = syncer.New2[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string]( + syncer.WithInsert[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error { + return f.db.InsertFriend(ctx, value) + }), + syncer.WithDelete[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error { + return f.db.DeleteFriendDB(ctx, value.FriendUserID) + }), + syncer.WithUpdate[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, server, local *model_struct.LocalFriend) error { + return f.db.UpdateFriend(ctx, server) + }), + syncer.WithUUID[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(value *model_struct.LocalFriend) [2]string { + return [...]string{value.OwnerUserID, value.FriendUserID} + }), + syncer.WithNotice[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, state int, server, local *model_struct.LocalFriend) error { + switch state { + case syncer.Insert: + f.friendListener.OnFriendAdded(*server) + case syncer.Delete: + log.ZDebug(ctx, "syncer OnFriendDeleted", "local", local) + f.friendListener.OnFriendDeleted(*local) + case syncer.Update: + f.friendListener.OnFriendInfoChanged(*server) + if local.Nickname != server.Nickname || local.FaceURL != server.FaceURL || local.Remark != server.Remark { + if server.Remark != "" { + server.Nickname = server.Remark + } + _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{ + Action: constant.UpdateConFaceUrlAndNickName, + Args: common.SourceIDAndSessionType{ + SourceID: server.FriendUserID, + SessionType: constant.SingleChatType, + FaceURL: server.FaceURL, + Nickname: server.Nickname, + }, + }, f.conversationCh) + _ = common.TriggerCmdUpdateMessage(ctx, common.UpdateMessageNode{ + Action: constant.UpdateMsgFaceUrlAndNickName, + Args: common.UpdateMessageInfo{ + SessionType: constant.SingleChatType, + UserID: server.FriendUserID, + FaceURL: server.FaceURL, + Nickname: server.Nickname, + }, + }, f.conversationCh) } - _ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.UpdateConFaceUrlAndNickName, - Args: common.SourceIDAndSessionType{SourceID: server.FriendUserID, SessionType: constant.SingleChatType, FaceURL: server.FaceURL, Nickname: server.Nickname}}, f.conversationCh) - _ = common.TriggerCmdUpdateMessage(ctx, common.UpdateMessageNode{Action: constant.UpdateMsgFaceUrlAndNickName, - Args: common.UpdateMessageInfo{SessionType: constant.SingleChatType, UserID: server.FriendUserID, FaceURL: server.FaceURL, Nickname: server.Nickname}}, f.conversationCh) } + return nil + }), + syncer.WithBatchInsert[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, values []*model_struct.LocalFriend) error { + log.ZDebug(ctx, "BatchInsertFriend", "length", len(values)) + return f.db.BatchInsertFriend(ctx, values) + }), + syncer.WithDeleteAll[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, _ string) error { + return f.db.DeleteAllFriend(ctx) + }), + syncer.WithBatchPageReq[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(entityID string) page.PageReq { + return &friend.GetPaginationFriendsReq{UserID: entityID, + Pagination: &sdkws.RequestPagination{ShowNumber: 100}} + }), + syncer.WithBatchPageRespConvertFunc[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(resp *friend.GetPaginationFriendsResp) []*model_struct.LocalFriend { + return datautil.Batch(ServerFriendToLocalFriend, resp.FriendsInfo) + }), + syncer.WithReqApiRouter[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](constant.GetFriendListRouter), + ) - } - return nil - }) f.blockSyncer = syncer.New[*model_struct.LocalBlack, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalBlack) error { return f.db.InsertBlack(ctx, value) }, func(ctx context.Context, value *model_struct.LocalBlack) error { diff --git a/internal/friend/sync.go b/internal/friend/sync.go index ea667d233..21caef624 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -16,6 +16,9 @@ package friend import ( "context" + "fmt" + "github.com/openimsdk/tools/utils/datautil" + "time" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -34,9 +37,9 @@ func (f *Friend) SyncBothFriendRequest(ctx context.Context, fromUserID, toUserID return err } if toUserID == f.loginUserID { - return f.requestRecvSyncer.Sync(ctx, util.Batch(ServerFriendRequestToLocalFriendRequest, resp.FriendRequests), localData, nil) + return f.requestRecvSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, resp.FriendRequests), localData, nil) } else if fromUserID == f.loginUserID { - return f.requestSendSyncer.Sync(ctx, util.Batch(ServerFriendRequestToLocalFriendRequest, resp.FriendRequests), localData, nil) + return f.requestSendSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, resp.FriendRequests), localData, nil) } return nil } @@ -55,7 +58,7 @@ func (f *Friend) SyncAllSelfFriendApplication(ctx context.Context) error { if err != nil { return err } - return f.requestSendSyncer.Sync(ctx, util.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) + return f.requestSendSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) } // recv @@ -70,10 +73,17 @@ func (f *Friend) SyncAllFriendApplication(ctx context.Context) error { if err != nil { return err } - return f.requestRecvSyncer.Sync(ctx, util.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) + return f.requestRecvSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) } func (f *Friend) SyncAllFriendList(ctx context.Context) error { + t := time.Now() + defer func(start time.Time) { + + elapsed := time.Since(start).Milliseconds() + log.ZDebug(ctx, "SyncAllFriendList fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) + + }(t) return f.IncrSyncFriends(ctx) //req := &friend.GetPaginationFriendsReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} //fn := func(resp *friend.GetPaginationFriendsResp) []*sdkws.FriendInfo { return resp.FriendsInfo } @@ -158,7 +168,7 @@ func (f *Friend) SyncAllBlackList(ctx context.Context) error { return err } log.ZDebug(ctx, "black from local", "data", localData) - return f.blockSyncer.Sync(ctx, util.Batch(ServerBlackToLocalBlack, serverData), localData, nil) + return f.blockSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil) } func (f *Friend) GetDesignatedFriends(ctx context.Context, friendIDs []string) ([]*sdkws.FriendInfo, error) { diff --git a/internal/friend/sync2.go b/internal/friend/sync2.go index 06b26a3b3..58653e57a 100644 --- a/internal/friend/sync2.go +++ b/internal/friend/sync2.go @@ -2,8 +2,12 @@ package friend import ( "context" - + "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + friend "github.com/openimsdk/protocol/relation" + "github.com/openimsdk/tools/utils/datautil" ) const ( @@ -11,43 +15,56 @@ const ( ) func (f *Friend) IncrSyncFriends(ctx context.Context) error { - //opt := incrversion.Option[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ - // Ctx: ctx, - // DB: f.db, - // Key: func(localFriend *model_struct.LocalFriend) string { - // return localFriend.FriendUserID - // }, - // SyncKey: func() string { - // return "friend:" + f.loginUserID - // }, - // Local: func() ([]*model_struct.LocalFriend, error) { - // return f.db.GetAllFriendList(ctx) - // }, - // Server: func(version *model_struct.LocalVersionSync) (*friend.GetIncrementalFriendsResp, error) { - // return util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, &friend.GetIncrementalFriendsReq{ - // UserID: f.loginUserID, - // Version: version.Version, - // VersionID: version.VersionID, - // }) - // }, - // Full: func(resp *friend.GetIncrementalFriendsResp) bool { - // return resp.Full - // }, - // Version: func(resp *friend.GetIncrementalFriendsResp) (string, uint64) { - // return resp.VersionID, resp.Version - // }, - // DeleteIDs: func(resp *friend.GetIncrementalFriendsResp) []string { - // return resp.DeleteUserIds - // }, - // Changes: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { - // return util.Batch(ServerFriendToLocalFriend, resp.Changes) - // }, - // Syncer: func(server, local []*model_struct.LocalFriend) error { - // return f.friendSyncer.Sync(ctx, server, local, nil) - // }, - //} - //return opt.Sync() - return nil + friendSyncer := incrversion.VersionSynchronizer[*model_struct.LocalFriend, *friend.GetIncrementalFriendsResp]{ + Ctx: ctx, + DB: f.db, + TableName: f.friendListTableName(), + EntityID: f.loginUserID, + Key: func(localFriend *model_struct.LocalFriend) string { + return localFriend.FriendUserID + }, + Local: func() ([]*model_struct.LocalFriend, error) { + return f.db.GetAllFriendList(ctx) + }, + Server: func(version *model_struct.LocalVersionSync) (*friend.GetIncrementalFriendsResp, error) { + return util.CallApi[friend.GetIncrementalFriendsResp](ctx, constant.GetIncrementalFriends, &friend.GetIncrementalFriendsReq{ + UserID: f.loginUserID, + Version: version.Version, + VersionID: version.VersionID, + }) + }, + Full: func(resp *friend.GetIncrementalFriendsResp) bool { + return resp.Full + }, + Version: func(resp *friend.GetIncrementalFriendsResp) (string, uint64) { + return resp.VersionID, resp.Version + }, + Delete: func(resp *friend.GetIncrementalFriendsResp) []string { + return resp.Delete + }, + Update: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { + return datautil.Batch(ServerFriendToLocalFriend, resp.Update) + }, + Insert: func(resp *friend.GetIncrementalFriendsResp) []*model_struct.LocalFriend { + return datautil.Batch(ServerFriendToLocalFriend, resp.Insert) + }, + Syncer: func(server, local []*model_struct.LocalFriend) error { + return f.friendSyncer.Sync(ctx, server, local, nil) + }, + FullSyncer: func(ctx context.Context) error { + return f.friendSyncer.FullSync(ctx, f.loginUserID) + }, + FullID: func(ctx context.Context) ([]string, error) { + resp, err := util.CallApi[friend.GetFullFriendUserIDsResp](ctx, constant.GetFullFriendUserIDs, &friend.GetFullFriendUserIDsReq{ + UserID: f.loginUserID, + }) + if err != nil { + return nil, err + } + return resp.UserIDs, nil + }, + } + return friendSyncer.Sync() } func (f *Friend) friendListTableName() string { diff --git a/internal/group/group.go b/internal/group/group.go index 928f219e3..6574f3d9e 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -71,7 +71,7 @@ func (g *Group) initSyncer() { if err := g.db.DeleteGroupAllMembers(ctx, value.GroupID); err != nil { return err } - if err := g.db.DeleteVersionSync(ctx, g.groupMemberTableName(), value.GroupID); err != nil { + if err := g.db.DeleteVersionSync(ctx, g.groupAndMemberVersionTableName(), value.GroupID); err != nil { return err } return g.db.DeleteGroup(ctx, value.GroupID) @@ -183,8 +183,8 @@ func (g *Group) initSyncer() { syncer.WithBatchInsert[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, values []*model_struct.LocalGroupMember) error { return g.db.BatchInsertGroupMember(ctx, values) }), - syncer.WithDeleteAll[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, entityID string) error { - return g.db.DeleteGroupAllMembers(ctx, entityID) + syncer.WithDeleteAll[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, groupID string) error { + return g.db.DeleteGroupAllMembers(ctx, groupID) }), syncer.WithBatchPageReq[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(entityID string) page.PageReq { return &group.GetGroupMemberListReq{GroupID: entityID, Pagination: &sdkws.RequestPagination{ShowNumber: 100}} diff --git a/internal/group/notification.go b/internal/group/notification.go index 2d08da478..c691069b4 100644 --- a/internal/group/notification.go +++ b/internal/group/notification.go @@ -16,8 +16,6 @@ package group import ( "context" - "encoding/json" - "errors" "fmt" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" @@ -43,16 +41,19 @@ func (g *Group) doNotification(ctx context.Context, msg *sdkws.MsgData) error { if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - if err := g.SyncGroups(ctx, detail.Group.GroupID); err != nil { + + if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) + return g.IncrSyncGroupAndMember(ctx, detail.Group.GroupID) + case constant.GroupInfoSetNotification: // 1502 var detail sdkws.GroupInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.SyncGroups(ctx, detail.Group.GroupID) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + nil, nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.JoinGroupApplicationNotification: // 1503 var detail sdkws.JoinGroupApplicationTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { @@ -63,255 +64,16 @@ func (g *Group) doNotification(ctx context.Context, msg *sdkws.MsgData) error { } else { return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) } - case constant.GroupApplicationAcceptedNotification: // 1505 - var detail sdkws.GroupApplicationAcceptedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - switch detail.ReceiverAs { - case 0: - return g.SyncAllSelfGroupApplication(ctx) - case 1: - return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) - default: - return fmt.Errorf("GroupApplicationAcceptedNotification ReceiverAs unknown %d", detail.ReceiverAs) - } - case constant.GroupApplicationRejectedNotification: // 1506 - var detail sdkws.GroupApplicationRejectedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - switch detail.ReceiverAs { - case 0: - return g.SyncAllSelfGroupApplication(ctx) - case 1: - return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) - default: - return fmt.Errorf("GroupApplicationRejectedNotification ReceiverAs unknown %d", detail.ReceiverAs) - } - case constant.GroupOwnerTransferredNotification: // 1507 - var detail sdkws.GroupOwnerTransferredTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - if err := g.SyncGroups(ctx, detail.Group.GroupID); err != nil { - return err - } - if detail.Group == nil { - return errors.New(fmt.Sprintf("group is nil, groupID: %s", detail.Group.GroupID)) - } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) - case constant.MemberKickedNotification: // 1508 - var detail sdkws.MemberKickedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - var self bool - for _, info := range detail.KickedUserList { - if info.UserID == g.loginUserID { - self = true - break - } - } - if self { - members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) - if err != nil { - return err - } - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - for _, member := range members { - data, err := json.Marshal(member) - if err != nil { - return err - } - g.listener().OnGroupMemberDeleted(string(data)) - } - group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) - if err != nil { - return err - } - group.MemberCount = 0 - data, err := json.Marshal(group) - if err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - g.listener().OnGroupInfoChanged(string(data)) - g.listener().OnJoinedGroupDeleted(string(data)) - return nil - } else { - var userIDs []string - for _, info := range detail.KickedUserList { - userIDs = append(userIDs, info.UserID) - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, userIDs...) - } case constant.MemberQuitNotification: // 1504 var detail sdkws.MemberQuitTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } if detail.QuitUser.UserID == g.loginUserID { - members, err := g.db.GetGroupMemberListSplit(ctx, detail.Group.GroupID, 0, 0, 999999) - if err != nil { - return err - } - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - for _, member := range members { - data, err := json.Marshal(member) - if err != nil { - return err - } - g.listener().OnGroupMemberDeleted(string(data)) - } - group, err := g.db.GetGroupInfoByGroupID(ctx, detail.Group.GroupID) - if err != nil { - return err - } - group.MemberCount = 0 - data, err := json.Marshal(group) - if err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - g.listener().OnGroupInfoChanged(string(data)) - return nil - } else { - //return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, nil, nil, detail.GroupMemberVersion) - } - case constant.MemberInvitedNotification: // 1509 - var detail sdkws.MemberInvitedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - if err := g.SyncGroups(ctx, detail.Group.GroupID); err != nil { - return err - } - var userIDs []string - for _, info := range detail.InvitedUserList { - userIDs = append(userIDs, info.UserID) - } - - if utils.IsContain(g.loginUserID, userIDs) { - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) - } else { - return g.SyncGroupMembers(ctx, detail.Group.GroupID, userIDs...) - } - case constant.MemberEnterNotification: // 1510 - var detail sdkws.MemberEnterTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - if detail.EntrantUser.UserID == g.loginUserID { - if err := g.SyncGroups(ctx, detail.Group.GroupID); err != nil { - return err - } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) - } else { - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.EntrantUser.UserID) - } - case constant.GroupDismissedNotification: // 1511 - var detail sdkws.GroupDismissedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - g.listener().OnGroupDismissed(utils.StructToJsonString(detail.Group)) - if err := g.db.DeleteGroupAllMembers(ctx, detail.Group.GroupID); err != nil { - return err - } - if err := g.db.DeleteGroup(ctx, detail.Group.GroupID); err != nil { - return err - } - return g.SyncAllGroupMember(ctx, detail.Group.GroupID) - case constant.GroupMemberMutedNotification: // 1512 - var detail sdkws.GroupMemberMutedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) - case constant.GroupMemberCancelMutedNotification: // 1513 - var detail sdkws.GroupMemberCancelMutedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.MutedUser.UserID) - case constant.GroupMutedNotification: // 1514 - return g.SyncGroups(ctx, msg.GroupID) - case constant.GroupCancelMutedNotification: // 1515 - return g.SyncGroups(ctx, msg.GroupID) - case constant.GroupMemberInfoSetNotification: // 1516 - var detail sdkws.GroupMemberInfoSetTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) //detail.ChangedUser.UserID - case constant.GroupMemberSetToAdminNotification: // 1517 - var detail sdkws.GroupMemberInfoSetTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) - case constant.GroupMemberSetToOrdinaryUserNotification: // 1518 - var detail sdkws.GroupMemberInfoSetTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.ChangedUser.UserID) - case constant.GroupInfoSetAnnouncementNotification: // 1519 - var detail sdkws.GroupInfoSetAnnouncementTips // - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroups(ctx, detail.Group.GroupID) - case constant.GroupInfoSetNameNotification: // 1520 - var detail sdkws.GroupInfoSetNameTips // - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.SyncGroups(ctx, detail.Group.GroupID) - default: - return fmt.Errorf("unknown tips type: %d", msg.ContentType) - } -} - -func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { - switch msg.ContentType { - case constant.GroupCreatedNotification: // 1501 - var detail sdkws.GroupCreatedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } - return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) - - case constant.GroupInfoSetNotification: // 1502 - var detail sdkws.GroupInfoSetTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - return g.IncrSyncJoinGroup(ctx) - case constant.JoinGroupApplicationNotification: // 1503 - var detail sdkws.JoinGroupApplicationTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - if detail.Applicant.UserID == g.loginUserID { - return g.SyncSelfGroupApplications(ctx, detail.Group.GroupID) + return g.IncrSyncJoinGroup(ctx) } else { - return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, + nil, nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) } case constant.GroupApplicationAcceptedNotification: // 1505 var detail sdkws.GroupApplicationAcceptedTips @@ -324,7 +86,7 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { case 1: return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) default: - return fmt.Errorf("GroupApplicationAcceptedNotification ReceiverAs unknown %d", detail.ReceiverAs) + return errs.New(fmt.Sprintf("GroupApplicationAcceptedNotification ReceiverAs unknown %d", detail.ReceiverAs)).Wrap() } case constant.GroupApplicationRejectedNotification: // 1506 var detail sdkws.GroupApplicationRejectedTips @@ -337,20 +99,19 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { case 1: return g.SyncAdminGroupApplications(ctx, detail.Group.GroupID) default: - return fmt.Errorf("GroupApplicationRejectedNotification ReceiverAs unknown %d", detail.ReceiverAs) + return errs.New(fmt.Sprintf("GroupApplicationRejectedNotification ReceiverAs unknown %d", detail.ReceiverAs)).Wrap() } case constant.GroupOwnerTransferredNotification: // 1507 var detail sdkws.GroupOwnerTransferredTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } if detail.Group == nil { - return errs.New(fmt.Sprintf("group is nil, groupID: %s", detail.Group.GroupID)) + return errs.New(fmt.Sprintf("group is nil, groupID: %s", detail.Group.GroupID)).Wrap() } - return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.NewGroupOwner, detail.OldGroupOwnerInfo}, nil, + detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.MemberKickedNotification: // 1508 var detail sdkws.MemberKickedTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { @@ -366,20 +127,8 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { if self { return g.IncrSyncJoinGroup(ctx) } else { - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - detail.KickedUserList, nil, detail.GroupMemberVersion) - } - case constant.MemberQuitNotification: // 1504 - var detail sdkws.MemberQuitTips - if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { - return err - } - if detail.QuitUser.UserID == g.loginUserID { - return g.IncrSyncJoinGroup(ctx) - } else { - //return g.SyncGroupMembers(ctx, detail.Group.GroupID, detail.QuitUser.UserID) - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, []*sdkws.GroupMemberFullInfo{detail.QuitUser}, - nil, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, detail.KickedUserList, nil, + nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) } case constant.MemberInvitedNotification: // 1509 var detail sdkws.MemberInvitedTips @@ -394,10 +143,10 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + return g.IncrSyncGroupAndMember(ctx, detail.Group.GroupID) } else { - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, - detail.InvitedUserList, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, nil, + detail.InvitedUserList, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) } case constant.MemberEnterNotification: // 1510 var detail sdkws.MemberEnterTips @@ -408,10 +157,10 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { if err := g.IncrSyncJoinGroup(ctx); err != nil { return err } - return g.IncrSyncGroupMember(ctx, detail.Group.GroupID) + return g.IncrSyncGroupAndMember(ctx, detail.Group.GroupID) } else { - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, nil, - []*sdkws.GroupMemberFullInfo{detail.EntrantUser}, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, nil, + []*sdkws.GroupMemberFullInfo{detail.EntrantUser}, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) } case constant.GroupDismissedNotification: // 1511 var detail sdkws.GroupDismissedTips @@ -426,54 +175,71 @@ func (g *Group) doNotification2(ctx context.Context, msg *sdkws.MsgData) error { if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, nil, + detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupMemberCancelMutedNotification: // 1513 var detail sdkws.GroupMemberCancelMutedTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.MutedUser}, nil, nil, + detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupMutedNotification: // 1514 - return g.IncrSyncJoinGroup(ctx) + var detail sdkws.GroupMutedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, nil, + nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupCancelMutedNotification: // 1515 - return g.IncrSyncJoinGroup(ctx) + var detail sdkws.GroupCancelMutedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { + return err + } + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, nil, + nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupMemberInfoSetNotification: // 1516 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, nil, + detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupMemberSetToAdminNotification: // 1517 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, nil, + detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupMemberSetToOrdinaryUserNotification: // 1518 var detail sdkws.GroupMemberInfoSetTips if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.onlineSyncGroupMember(ctx, detail.Group.GroupID, nil, - []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, detail.GroupMemberVersion) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + []*sdkws.GroupMemberFullInfo{detail.ChangedUser}, nil, nil, + detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupInfoSetAnnouncementNotification: // 1519 var detail sdkws.GroupInfoSetAnnouncementTips // if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.IncrSyncJoinGroup(ctx) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, nil, + nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) case constant.GroupInfoSetNameNotification: // 1520 var detail sdkws.GroupInfoSetNameTips // if err := utils.UnmarshalNotificationElem(msg.Content, &detail); err != nil { return err } - return g.IncrSyncJoinGroup(ctx) + return g.onlineSyncGroupAndMember(ctx, detail.Group.GroupID, nil, + nil, nil, detail.Group, detail.GroupMemberVersion, detail.GroupMemberVersionID) default: - return fmt.Errorf("unknown tips type: %d", msg.ContentType) + return errs.New("unknown tips type", "contentType", msg.ContentType).Wrap() } } diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 9f5c4a6e6..ba4bb78dd 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -48,7 +48,7 @@ func (g *Group) CreateGroup(ctx context.Context, req *group.CreateGroupReq) (*sd if err := g.IncrSyncJoinGroup(ctx); err != nil { return nil, err } - if err := g.IncrSyncGroupMember(ctx, resp.GroupInfo.GroupID); err != nil { + if err := g.IncrSyncGroupAndMember(ctx, resp.GroupInfo.GroupID); err != nil { return nil, err } return resp.GroupInfo, nil @@ -87,7 +87,7 @@ func (g *Group) ChangeGroupMute(ctx context.Context, groupID string, isMute bool if err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { + if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { return err } return nil @@ -117,7 +117,7 @@ func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.S if err := util.ApiPost(ctx, constant.SetGroupMemberInfoRouter, &group.SetGroupMemberInfoReq{Members: []*group.SetGroupMemberInfo{groupMemberInfo}}, nil); err != nil { return err } - return g.IncrSyncGroupMember(ctx, groupMemberInfo.GroupID) + return g.IncrSyncGroupAndMember(ctx, groupMemberInfo.GroupID) } func (g *Group) GetJoinedGroupList(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, error) { @@ -167,7 +167,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( for i := range groups.GroupInfos { groups.GroupInfos[i].MemberCount = 0 } - res = append(res, util.Batch(ServerGroupToLocalGroup, groups.GroupInfos)...) + res = append(res, datautil.Batch(ServerGroupToLocalGroup, groups.GroupInfos)...) } } return res, nil @@ -212,13 +212,13 @@ func (g *Group) SetGroupInfo(ctx context.Context, groupInfo *sdkws.GroupInfoForS if err := util.ApiPost(ctx, constant.SetGroupInfoRouter, &group.SetGroupInfoReq{GroupInfoForSet: groupInfo}, nil); err != nil { return err } - return g.IncrSyncJoinGroup(ctx) + return g.IncrSyncGroupAndMember(ctx) } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -260,17 +260,14 @@ func (g *Group) KickGroupMember(ctx context.Context, groupID string, reason stri if err := util.ApiPost(ctx, constant.KickGroupMemberRouter, &group.KickGroupMemberReq{GroupID: groupID, KickedUserIDs: userIDList, Reason: reason}, nil); err != nil { return err } - return g.IncrSyncGroupMember(ctx, groupID) + return g.IncrSyncGroupAndMember(ctx, groupID) } func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID string) error { if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } - if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { + if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { return err } return nil @@ -280,10 +277,7 @@ func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, u if err := util.ApiPost(ctx, constant.InviteUserToGroupRouter, &group.InviteUserToGroupReq{GroupID: groupID, Reason: reason, InvitedUserIDs: userIDList}, nil); err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } - if err := g.IncrSyncGroupMember(ctx, groupID); err != nil { + if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { return err } return nil diff --git a/internal/group/sync.go b/internal/group/sync.go index 8e839f6b3..ff3ed1040 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -85,12 +85,12 @@ func (g *Group) SyncAllGroupMember(ctx context.Context, groupID string) error { } func (g *Group) SyncAllGroupMember2(ctx context.Context, groupID string) error { - return g.IncrSyncGroupMember(ctx, groupID) + return g.IncrSyncGroupAndMember(ctx, groupID) } func (g *Group) syncGroupMembers(ctx context.Context, groupID string, members []*sdkws.GroupMemberFullInfo, localData []*model_struct.LocalGroupMember) error { log.ZInfo(ctx, "SyncGroupMember Info", "groupID", groupID, "members", len(members), "localData", len(localData)) - err := g.groupMemberSyncer.Sync(ctx, util.Batch(ServerGroupMemberToLocalGroupMember, members), localData, nil) + err := g.groupMemberSyncer.Sync(ctx, datautil.Batch(ServerGroupMemberToLocalGroupMember, members), localData, nil) if err != nil { return err } @@ -132,7 +132,7 @@ func (g *Group) syncGroupMembers(ctx context.Context, groupID string, members [] } func (g *Group) SyncGroupMembers(ctx context.Context, groupID string, userIDs ...string) error { - return g.IncrSyncGroupMember(ctx, groupID) + return g.IncrSyncGroupAndMember(ctx, groupID) //members, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) //if err != nil { // return err @@ -225,7 +225,7 @@ func (g *Group) syncAllJoinedGroups(ctx context.Context) ([]*sdkws.GroupInfo, er if err != nil { return nil, err } - if err := g.groupSyncer.Sync(ctx, util.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { + if err := g.groupSyncer.Sync(ctx, datautil.Batch(ServerGroupToLocalGroup, groups), localData, nil); err != nil { return nil, err } return groups, nil @@ -240,7 +240,7 @@ func (g *Group) SyncAllSelfGroupApplication(ctx context.Context) error { if err != nil { return err } - if err := g.groupRequestSyncer.Sync(ctx, util.Batch(ServerGroupRequestToLocalGroupRequest, list), localData, nil); err != nil { + if err := g.groupRequestSyncer.Sync(ctx, datautil.Batch(ServerGroupRequestToLocalGroupRequest, list), localData, nil); err != nil { return err } // todo @@ -260,7 +260,7 @@ func (g *Group) SyncAllAdminGroupApplication(ctx context.Context) error { if err != nil { return err } - return g.groupAdminRequestSyncer.Sync(ctx, util.Batch(ServerGroupRequestToLocalAdminGroupRequest, requests), localData, nil) + return g.groupAdminRequestSyncer.Sync(ctx, datautil.Batch(ServerGroupRequestToLocalAdminGroupRequest, requests), localData, nil) } func (g *Group) SyncAdminGroupApplications(ctx context.Context, groupIDs ...string) error { diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 58e522ec6..bf4cf3281 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -32,8 +32,8 @@ func (g *Group) getIncrementalGroupMemberBatch(ctx context.Context, groups []*gr return resp.List, nil } -func (g *Group) groupMemberTableName() string { - return model_struct.LocalGroupMember{}.TableName() +func (g *Group) groupAndMemberVersionTableName() string { + return "local_group_entities_version" } func (g *Group) groupTableName() string { @@ -48,10 +48,10 @@ func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { groupIDs := datautil.Slice(groups, func(e *model_struct.LocalGroup) string { return e.GroupID }) - return g.IncrSyncGroupMember(ctx, groupIDs...) + return g.IncrSyncGroupAndMember(ctx, groupIDs...) } -func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) error { +func (g *Group) IncrSyncGroupAndMember(ctx context.Context, groupIDs ...string) error { var wg sync.WaitGroup if len(groupIDs) == 0 { return nil @@ -75,7 +75,7 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err req := group.GetIncrementalGroupMemberReq{ GroupID: groupID, } - lvs, err := g.db.GetVersionSync(ctx, g.groupMemberTableName(), groupID) + lvs, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) if err == nil { req.VersionID = lvs.VersionID req.Version = lvs.Version @@ -94,7 +94,7 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err tempGroupID := groupID wg.Add(1) go func() error { - if err := g.syncGroupMember(ctx, tempGroupID, tempResp); err != nil { + if err := g.syncGroupAndMember(ctx, tempGroupID, tempResp); err != nil { return err } wg.Done() @@ -108,11 +108,11 @@ func (g *Group) IncrSyncGroupMember(ctx context.Context, groupIDs ...string) err } } -func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group.GetIncrementalGroupMemberResp) error { +func (g *Group) syncGroupAndMember(ctx context.Context, groupID string, resp *group.GetIncrementalGroupMemberResp) error { groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ Ctx: ctx, DB: g.db, - TableName: g.groupMemberTableName(), + TableName: g.groupAndMemberVersionTableName(), EntityID: groupID, Key: func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -138,6 +138,29 @@ func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group Insert: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Insert) }, + ExtraData: func(resp *group.GetIncrementalGroupMemberResp) any { + return resp.Group + }, + ExtraDataProcessor: func(ctx context.Context, data any) error { + local, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + groupInfo, ok := data.(*sdkws.GroupInfo) + if !ok { + return errs.New("group info type error") + } + changes := datautil.Batch(ServerGroupToLocalGroup, []*sdkws.GroupInfo{groupInfo}) + kv := datautil.SliceToMapAny(local, func(e *model_struct.LocalGroup) (string, *model_struct.LocalGroup) { + return e.GroupID, e + }) + for i, change := range changes { + key := change.GroupID + kv[key] = changes[i] + } + server := datautil.Values(kv) + return g.groupSyncer.Sync(ctx, server, local, nil) + }, Syncer: func(server, local []*model_struct.LocalGroupMember) error { return g.groupMemberSyncer.Sync(ctx, server, local, nil) }, @@ -145,7 +168,7 @@ func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group return g.groupMemberSyncer.FullSync(ctx, groupID) }, FullID: func(ctx context.Context) ([]string, error) { - resp, err := util.CallApi[group.GetIncrementalGroupMemberUserIDsResp](ctx, constant.GetGroupMemberAllIDs, &group.GetIncrementalGroupMemberUserIDsReq{ + resp, err := util.CallApi[group.GetFullGroupMemberUserIDsResp](ctx, constant.GetFullGroupMemberUserIDs, &group.GetFullGroupMemberUserIDsReq{ GroupID: groupID, }) if err != nil { @@ -157,11 +180,12 @@ func (g *Group) syncGroupMember(ctx context.Context, groupID string, resp *group return groupMemberSyncer.Sync() } -func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delete, update, insert []*sdkws.GroupMemberFullInfo, version uint64) error { +func (g *Group) onlineSyncGroupAndMember(ctx context.Context, groupID string, deleteGroupMembers, updateGroupMembers, insertGroupMembers []*sdkws.GroupMemberFullInfo, + updateGroup *sdkws.GroupInfo, version uint64, versionID string) error { groupMemberSyncer := incrversion.VersionSynchronizer[*model_struct.LocalGroupMember, *group.GetIncrementalGroupMemberResp]{ Ctx: ctx, DB: g.db, - TableName: g.groupMemberTableName(), + TableName: g.groupAndMemberVersionTableName(), EntityID: groupID, Key: func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -172,13 +196,14 @@ func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delet ServerVersion: func() *group.GetIncrementalGroupMemberResp { return &group.GetIncrementalGroupMemberResp{ Version: version, - VersionID: "", + VersionID: versionID, Full: false, - Delete: datautil.Slice(delete, func(e *sdkws.GroupMemberFullInfo) string { + Delete: datautil.Slice(deleteGroupMembers, func(e *sdkws.GroupMemberFullInfo) string { return e.UserID }), - Insert: insert, - Update: update, + Insert: insertGroupMembers, + Update: updateGroupMembers, + Group: updateGroup, } }, Server: func(version *model_struct.LocalVersionSync) (*group.GetIncrementalGroupMemberResp, error) { @@ -215,6 +240,29 @@ func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delet Insert: func(resp *group.GetIncrementalGroupMemberResp) []*model_struct.LocalGroupMember { return datautil.Batch(ServerGroupMemberToLocalGroupMember, resp.Insert) }, + ExtraData: func(resp *group.GetIncrementalGroupMemberResp) any { + return resp.Group + }, + ExtraDataProcessor: func(ctx context.Context, data any) error { + local, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + groupInfo, ok := data.(*sdkws.GroupInfo) + if !ok { + return errs.New("group info type error") + } + changes := datautil.Batch(ServerGroupToLocalGroup, []*sdkws.GroupInfo{groupInfo}) + kv := datautil.SliceToMapAny(local, func(e *model_struct.LocalGroup) (string, *model_struct.LocalGroup) { + return e.GroupID, e + }) + for i, change := range changes { + key := change.GroupID + kv[key] = changes[i] + } + server := datautil.Values(kv) + return g.groupSyncer.Sync(ctx, server, local, nil) + }, Syncer: func(server, local []*model_struct.LocalGroupMember) error { return g.groupMemberSyncer.Sync(ctx, server, local, nil) }, @@ -222,7 +270,7 @@ func (g *Group) onlineSyncGroupMember(ctx context.Context, groupID string, delet return g.groupMemberSyncer.FullSync(ctx, groupID) }, FullID: func(ctx context.Context) ([]string, error) { - resp, err := util.CallApi[group.GetIncrementalGroupMemberUserIDsResp](ctx, constant.GetGroupMemberAllIDs, &group.GetIncrementalGroupMemberUserIDsReq{ + resp, err := util.CallApi[group.GetFullGroupMemberUserIDsResp](ctx, constant.GetFullGroupMemberUserIDs, &group.GetFullGroupMemberUserIDsReq{ GroupID: groupID, }) if err != nil { @@ -263,7 +311,7 @@ func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { return resp.Delete }, Update: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { - return util.Batch(ServerGroupToLocalGroup, resp.Update) + return datautil.Batch(ServerGroupToLocalGroup, resp.Update) }, Insert: func(resp *group.GetIncrementalJoinGroupResp) []*model_struct.LocalGroup { return datautil.Batch(ServerGroupToLocalGroup, resp.Insert) @@ -275,7 +323,7 @@ func (g *Group) IncrSyncJoinGroup(ctx context.Context) error { return g.groupSyncer.FullSync(ctx, g.loginUserID) }, FullID: func(ctx context.Context) ([]string, error) { - resp, err := util.CallApi[group.GetIncrementalJoinGroupIDsResp](ctx, constant.GetJoinedGroupAllIDs, &group.GetIncrementalJoinGroupIDsReq{ + resp, err := util.CallApi[group.GetFullJoinGroupIDsResp](ctx, constant.GetFullJoinedGroupIDs, &group.GetFullJoinGroupIDsReq{ UserID: g.loginUserID, }) if err != nil { diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index c961433e2..9d3d1aa67 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -12,22 +12,24 @@ import ( ) type VersionSynchronizer[V, R any] struct { - Ctx context.Context - DB db_interface.VersionSyncModel - TableName string - EntityID string - Key func(V) string - Local func() ([]V, error) - ServerVersion func() R - Server func(version *model_struct.LocalVersionSync) (R, error) - Full func(resp R) bool - Version func(resp R) (string, uint64) - Delete func(resp R) []string - Update func(resp R) []V - Insert func(resp R) []V - Syncer func(server, local []V) error - FullSyncer func(ctx context.Context) error - FullID func(ctx context.Context) ([]string, error) + Ctx context.Context + DB db_interface.VersionSyncModel + TableName string + EntityID string + Key func(V) string + Local func() ([]V, error) + ServerVersion func() R + Server func(version *model_struct.LocalVersionSync) (R, error) + Full func(resp R) bool + Version func(resp R) (string, uint64) + Delete func(resp R) []string + Update func(resp R) []V + Insert func(resp R) []V + ExtraData func(resp R) any + ExtraDataProcessor func(ctx context.Context, data any) error + Syncer func(server, local []V) error + FullSyncer func(ctx context.Context) error + FullID func(ctx context.Context) ([]string, error) } func (o *VersionSynchronizer[V, R]) getVersionInfo() (*model_struct.LocalVersionSync, error) { @@ -50,6 +52,7 @@ func (o *VersionSynchronizer[V, R]) updateVersionInfo(lvs *model_struct.LocalVer func (o *VersionSynchronizer[V, R]) Sync() error { var lvs *model_struct.LocalVersionSync var resp R + var extraData any if o.ServerVersion == nil { var err error lvs, err = o.getVersionInfo() @@ -71,8 +74,11 @@ func (o *VersionSynchronizer[V, R]) Sync() error { delIDs := o.Delete(resp) changes := o.Update(resp) insert := o.Insert(resp) + if o.ExtraData != nil { + extraData = o.ExtraData(resp) + } - if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && o.ExtraData == nil { log.ZDebug(o.Ctx, "no data to sync", "table", o.TableName, "entityID", o.EntityID) return nil } @@ -113,6 +119,12 @@ func (o *VersionSynchronizer[V, R]) Sync() error { if err := o.Syncer(server, local); err != nil { return err } + if extraData != nil && o.ExtraDataProcessor != nil { + if err := o.ExtraDataProcessor(o.Ctx, extraData); err != nil { + return err + } + + } } return o.updateVersionInfo(lvs, resp) } @@ -122,15 +134,26 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { if err != nil { return err } + var extraData any resp := o.ServerVersion() delIDs := o.Delete(resp) changes := o.Update(resp) insert := o.Insert(resp) - _, version := o.Version(resp) - if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) { + versionID, version := o.Version(resp) + if o.ExtraData != nil { + extraData = o.ExtraData(resp) + } + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && o.ExtraData == nil { log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TableName, "entityID", o.EntityID) return nil } + /// If the version unique ID cannot correspond with the local version, + // it indicates that the data might have been tampered with or an exception has occurred. + //Trigger the complete client-server incremental synchronization. + if versionID != lvs.VersionID { + o.ServerVersion = nil + return o.Sync() + } if lvs.Version+1 == version { if len(delIDs) > 0 { lvs.UIDList = DeleteElements(lvs.UIDList, delIDs) @@ -158,13 +181,21 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { if err := o.Syncer(server, local); err != nil { return err } + if extraData != nil && o.ExtraDataProcessor != nil { + if err := o.ExtraDataProcessor(o.Ctx, extraData); err != nil { + return err + } + + } return o.updateVersionInfo(lvs, resp) } else if version <= lvs.Version { log.ZWarn(o.Ctx, "version less than local version", errs.New("version less than local version"), "table", o.TableName, "entityID", o.EntityID, "version", version, "localVersion", lvs.Version) return nil } else { - // Re-fetch the version number from the server, compare it with the local version number, and fetch the difference once. + // If the version number has a gap with the local version number, + //it indicates that some pushed data might be missing. + //Trigger the complete client-server incremental synchronization. o.ServerVersion = nil return o.Sync() } diff --git a/internal/user/sync.go b/internal/user/sync.go index 0eb5c186d..e3fd118c0 100644 --- a/internal/user/sync.go +++ b/internal/user/sync.go @@ -22,6 +22,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" userPb "github.com/openimsdk/protocol/user" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -92,5 +93,5 @@ func (u *User) SyncAllCommand(ctx context.Context) error { return err } log.ZDebug(ctx, "sync command", "data from server", serverData, "data from local", localData) - return u.commandSyncer.Sync(ctx, util.Batch(ServerCommandToLocalCommand, serverData.CommandResp), localData, nil) + return u.commandSyncer.Sync(ctx, datautil.Batch(ServerCommandToLocalCommand, serverData.CommandResp), localData, nil) } diff --git a/internal/user/user.go b/internal/user/user.go index 40597513a..181930984 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -27,6 +27,7 @@ import ( "github.com/openimsdk/protocol/sdkws" userPb "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" @@ -262,7 +263,7 @@ func (u *User) GetUsersInfoFromSvr(ctx context.Context, userIDs []string) ([]*mo if err != nil { return nil, sdkerrs.WrapMsg(err, "GetUsersInfoFromSvr failed") } - return util.Batch(ServerUserToLocalUser, resp.UsersInfo), nil + return datautil.Batch(ServerUserToLocalUser, resp.UsersInfo), nil } // GetSingleUserFromSvr retrieves user information from the server. diff --git a/internal/util/conversion.go b/internal/util/conversion.go deleted file mode 100644 index d0ce7795e..000000000 --- a/internal/util/conversion.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright © 2023 OpenIM SDK. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -func Batch[T any, V any](fn func(T) V, ts []T) []V { - if ts == nil { - return nil - } - res := make([]V, 0, len(ts)) - for i := range ts { - res = append(res, fn(ts[i])) - } - return res -} diff --git a/internal/util/post.go b/internal/util/post.go index a5c27ceea..49414546a 100644 --- a/internal/util/post.go +++ b/internal/util/post.go @@ -210,7 +210,7 @@ func FetchAndInsertPagedData[RESP, L any](ctx context.Context, api string, req p req.GetPagination().ShowNumber = 50 } var errSingle error - errSingle = nil + var errList []error totalFetched := 0 for i := int32(0); ; i++ { req.GetPagination().PageNumber = i + 1 @@ -223,7 +223,7 @@ func FetchAndInsertPagedData[RESP, L any](ctx context.Context, api string, req p for _, item := range list { errSingle = insertFn(ctx, item) if errSingle != nil { - errSingle = errs.New(errSingle.Error(), "item", item) + errList = append(errList, errs.New(errSingle.Error(), "item", item)) } } } @@ -232,8 +232,8 @@ func FetchAndInsertPagedData[RESP, L any](ctx context.Context, api string, req p break } } - if errSingle != nil { - return errs.WrapMsg(errSingle, "batch insert failed due to data exception") + if len(errList) > 0 { + return errs.WrapMsg(errList[0], "batch insert failed due to data exception") } return nil } diff --git a/pkg/common/trigger_channel.go b/pkg/common/trigger_channel.go index a0a4a89c1..cb8d1f9cc 100644 --- a/pkg/common/trigger_channel.go +++ b/pkg/common/trigger_channel.go @@ -70,18 +70,6 @@ func TriggerCmdWakeUp(ch chan Cmd2Value) error { return sendCmd(ch, c2v, 100) } -func TriggerCmdDeleteConversationAndMessage(sourceID, conversationID string, sessionType int, conversationCh chan Cmd2Value) error { - if conversationCh == nil { - return utils.Wrap(errors.New("ch == nil"), "") - } - c2v := Cmd2Value{ - Cmd: constant.CmdDeleteConversation, - Value: DeleteConNode{SourceID: sourceID, ConversationID: conversationID, SessionType: sessionType}, - } - - return sendCmd(conversationCh, c2v, 100) -} - func TriggerCmdSyncReactionExtensions(node SyncReactionExtensionsNode, conversationCh chan Cmd2Value) error { if conversationCh == nil { return utils.Wrap(errors.New("ch == nil"), "") diff --git a/pkg/constant/server_api_router.go b/pkg/constant/server_api_router.go index 1462b779b..b512dcc22 100644 --- a/pkg/constant/server_api_router.go +++ b/pkg/constant/server_api_router.go @@ -46,6 +46,7 @@ const ( SetFriendRemark = "/friend/set_friend_remark" UpdateFriends = "/friend/update_friends" GetIncrementalFriends = "/friend/get_incremental_friends" + GetFullFriendUserIDs = "/friend/get_full_friend_user_ids" AddBlackRouter = "/friend/add_black" RemoveBlackRouter = "/friend/remove_black" @@ -107,8 +108,8 @@ const ( //SearchGroupMember = RouterGroup + "/search_group_member" GetIncrementalJoinGroup = RouterGroup + "/get_incremental_join_group" GetIncrementalGroupMemberBatch = RouterGroup + "/get_incremental_group_member_batch" - GetJoinedGroupAllIDs = RouterGroup + "/get_incremental_join_group_ids" - GetGroupMemberAllIDs = RouterGroup + "/get_incremental_group_member_user_ids" + GetFullJoinedGroupIDs = RouterGroup + "/get_full_join_group_ids" + GetFullGroupMemberUserIDs = RouterGroup + "/get_full_group_member_user_ids" SetReceiveMessageOptRouter = "/conversation/set_receive_message_opt" GetReceiveMessageOptRouter = "/conversation/get_receive_message_opt" diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index 9ada296e0..c2b9dd236 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -232,6 +232,7 @@ type FriendModel interface { GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error) GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error) BatchInsertFriend(ctx context.Context, friendList []*model_struct.LocalFriend) error + DeleteAllFriend(ctx context.Context) error SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error) GetFriendInfoByFriendUserID(ctx context.Context, FriendUserID string) (*model_struct.LocalFriend, error) diff --git a/pkg/db/friend_model.go b/pkg/db/friend_model.go index 65b3a0bae..6da7fd3de 100644 --- a/pkg/db/friend_model.go +++ b/pkg/db/friend_model.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + "gorm.io/gorm" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" @@ -90,6 +91,12 @@ func (d *DataBase) BatchInsertFriend(ctx context.Context, friendList []*model_st return errs.WrapMsg(d.conn.WithContext(ctx).Create(friendList).Error, "BatchInsertFriendList failed") } +func (d *DataBase) DeleteAllFriend(ctx context.Context) error { + d.friendMtx.Lock() + defer d.friendMtx.Unlock() + return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&model_struct.LocalFriend{}).Error, "DeleteAllFriend failed") +} + func (d *DataBase) SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() diff --git a/testv2/sync2_test.go b/testv2/sync2_test.go index d476bd8f4..16e9a0b19 100644 --- a/testv2/sync2_test.go +++ b/testv2/sync2_test.go @@ -48,7 +48,7 @@ func TestSyncJoinGroup2(t *testing.T) { func TestSyncGroupMember2(t *testing.T) { for i := 0; ; i++ { if err := open_im_sdk.UserForSDK.Group().IncrSyncJoinGroupMember(ctx); err != nil { - t.Log("IncrSyncGroupMember error-->", err) + t.Log("IncrSyncGroupAndMember error-->", err) continue } time.Sleep(time.Second) From 130b273e76395b80d2eb018f6baf5498f0b2bc92 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 10:53:15 +0800 Subject: [PATCH 27/69] rewrite data fetch. --- internal/group/sdk.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index df13f77e4..69cf873c8 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -232,7 +232,29 @@ func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID } func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupMemberTableName(), + groupID, + func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil + }, + ) + return dataFetcher.FetchMissingAndFillLocal(ctx, userIDList) + // return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { From 942a736601396ce45d230c1e26cb32865882fe1b Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:29:39 +0800 Subject: [PATCH 28/69] feat: friend full sync and incr sync. --- internal/group/sync2.go | 24 ++++++++++++++++-------- internal/incrversion/option.go | 20 ++++++++++++++++---- open_im_sdk_callback/callback_client.go | 6 ++++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/internal/group/sync2.go b/internal/group/sync2.go index bf4cf3281..71d7d530a 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -142,14 +142,18 @@ func (g *Group) syncGroupAndMember(ctx context.Context, groupID string, resp *gr return resp.Group }, ExtraDataProcessor: func(ctx context.Context, data any) error { - local, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return err - } groupInfo, ok := data.(*sdkws.GroupInfo) if !ok { return errs.New("group info type error") } + if groupInfo == nil { + return nil + } + local, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + log.ZDebug(ctx, "group info", "groupInfo", groupInfo) changes := datautil.Batch(ServerGroupToLocalGroup, []*sdkws.GroupInfo{groupInfo}) kv := datautil.SliceToMapAny(local, func(e *model_struct.LocalGroup) (string, *model_struct.LocalGroup) { return e.GroupID, e @@ -244,14 +248,18 @@ func (g *Group) onlineSyncGroupAndMember(ctx context.Context, groupID string, de return resp.Group }, ExtraDataProcessor: func(ctx context.Context, data any) error { - local, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return err - } groupInfo, ok := data.(*sdkws.GroupInfo) if !ok { return errs.New("group info type error") } + if groupInfo == nil { + return nil + } + local, err := g.db.GetJoinedGroupListDB(ctx) + if err != nil { + return err + } + log.ZDebug(ctx, "group info", "groupInfo", groupInfo) changes := datautil.Batch(ServerGroupToLocalGroup, []*sdkws.GroupInfo{groupInfo}) kv := datautil.SliceToMapAny(local, func(e *model_struct.LocalGroup) (string, *model_struct.LocalGroup) { return e.GroupID, e diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index 9d3d1aa67..112bc937a 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -8,6 +8,7 @@ import ( "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" "gorm.io/gorm" + "reflect" "sort" ) @@ -48,6 +49,9 @@ func (o *VersionSynchronizer[V, R]) updateVersionInfo(lvs *model_struct.LocalVer lvs.VersionID, lvs.Version = o.Version(resp) return o.DB.SetVersionSync(o.Ctx, lvs) } +func judgeInterfaceIsNil(data any) bool { + return reflect.ValueOf(data).Kind() == reflect.Ptr && reflect.ValueOf(data).IsNil() +} func (o *VersionSynchronizer[V, R]) Sync() error { var lvs *model_struct.LocalVersionSync @@ -75,10 +79,13 @@ func (o *VersionSynchronizer[V, R]) Sync() error { changes := o.Update(resp) insert := o.Insert(resp) if o.ExtraData != nil { - extraData = o.ExtraData(resp) + temp := o.ExtraData(resp) + if !judgeInterfaceIsNil(temp) { + extraData = temp + } } - if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && o.ExtraData == nil { + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && extraData == nil { log.ZDebug(o.Ctx, "no data to sync", "table", o.TableName, "entityID", o.EntityID) return nil } @@ -141,16 +148,21 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { insert := o.Insert(resp) versionID, version := o.Version(resp) if o.ExtraData != nil { - extraData = o.ExtraData(resp) + temp := o.ExtraData(resp) + if !judgeInterfaceIsNil(temp) { + extraData = temp + } } - if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && o.ExtraData == nil { + if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && extraData == nil { log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TableName, "entityID", o.EntityID) return nil } + log.ZDebug(o.Ctx, "check version sync", "table", o.TableName, "entityID", o.EntityID, "versionID", versionID, "localVersionID", lvs.VersionID, "version", version, "localVersion", lvs.Version) /// If the version unique ID cannot correspond with the local version, // it indicates that the data might have been tampered with or an exception has occurred. //Trigger the complete client-server incremental synchronization. if versionID != lvs.VersionID { + log.ZDebug(o.Ctx, "version id not match", errs.New("version id not match"), "versionID", versionID, "localVersionID", lvs.VersionID) o.ServerVersion = nil return o.Sync() } diff --git a/open_im_sdk_callback/callback_client.go b/open_im_sdk_callback/callback_client.go index 27ba5e802..e5643cdad 100644 --- a/open_im_sdk_callback/callback_client.go +++ b/open_im_sdk_callback/callback_client.go @@ -150,3 +150,9 @@ type UploadFileCallback interface { type UploadLogProgress interface { OnProgress(current int64, size int64) } + +type AppDataSyncListener interface { + OnAppDataSyncStart() + OnAppDataSyncProgress(progress int) + OnAppDataSyncFinish() +} From 9fbc7fe7160f7e461a91124e6f246132ab5e9023 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 18:34:50 +0800 Subject: [PATCH 29/69] fix: fix uncorrect range variable implement. --- internal/incrversion/option.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index 112bc937a..947c0683d 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -2,14 +2,15 @@ package incrversion import ( "context" + "reflect" + "sort" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" "gorm.io/gorm" - "reflect" - "sort" ) type VersionSynchronizer[V, R any] struct { @@ -84,7 +85,7 @@ func (o *VersionSynchronizer[V, R]) Sync() error { extraData = temp } } - + log.ZDebug(o.Ctx, "Sync panic", "changes", changes, "insert", insert, "delIDs", delIDs) if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && extraData == nil { log.ZDebug(o.Ctx, "no data to sync", "table", o.TableName, "entityID", o.EntityID) return nil @@ -114,7 +115,10 @@ func (o *VersionSynchronizer[V, R]) Sync() error { kv := datautil.SliceToMapAny(local, func(v V) (string, V) { return o.Key(v), v }) - for i, change := range append(changes, insert...) { + + changes = append(changes, insert...) + + for i, change := range changes { key := o.Key(change) kv[key] = changes[i] } From 1d468f8890045b11d627f5950ef82b70a22654f9 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 18:36:16 +0800 Subject: [PATCH 30/69] refactor: refactor data fetch impl. --- internal/friend/friend.go | 114 +---------------------------- internal/friend/notification.go | 121 +++++++++++++++++++++++++++++++ internal/interaction/msg_sync.go | 4 +- open_im_sdk/group.go | 41 ++++++----- 4 files changed, 146 insertions(+), 134 deletions(-) diff --git a/internal/friend/friend.go b/internal/friend/friend.go index 5835f6996..33fe3f4e9 100644 --- a/internal/friend/friend.go +++ b/internal/friend/friend.go @@ -16,7 +16,7 @@ package friend import ( "context" - "fmt" + "github.com/openimsdk/openim-sdk-core/v3/internal/user" "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" @@ -25,7 +25,6 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/page" "github.com/openimsdk/openim-sdk-core/v3/pkg/syncer" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" friend "github.com/openimsdk/protocol/relation" "github.com/openimsdk/tools/utils/datautil" @@ -198,114 +197,3 @@ func (f *Friend) SetListener(listener func() open_im_sdk_callback.OnFriendshipLi func (f *Friend) SetListenerForService(listener open_im_sdk_callback.OnListenerForService) { f.listenerForService = listener } - -func (f *Friend) DoNotification(ctx context.Context, msg *sdkws.MsgData) { - go func() { - if err := f.doNotification(ctx, msg); err != nil { - log.ZError(ctx, "doNotification error", err, "msg", msg) - } - }() -} - -func (f *Friend) doNotification(ctx context.Context, msg *sdkws.MsgData) error { - switch msg.ContentType { - case constant.FriendApplicationNotification: - tips := sdkws.FriendApplicationTips{} - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - return f.SyncBothFriendRequest(ctx, - tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) - case constant.FriendApplicationApprovedNotification: - var tips sdkws.FriendApplicationApprovedTips - err := utils.UnmarshalNotificationElem(msg.Content, &tips) - if err != nil { - return err - } - - if tips.FromToUserID.FromUserID == f.loginUserID { - err = f.SyncFriends(ctx, []string{tips.FromToUserID.ToUserID}) - } else if tips.FromToUserID.ToUserID == f.loginUserID { - err = f.SyncFriends(ctx, []string{tips.FromToUserID.FromUserID}) - } - if err != nil { - return err - } - return f.SyncBothFriendRequest(ctx, tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) - case constant.FriendApplicationRejectedNotification: - var tips sdkws.FriendApplicationRejectedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - return f.SyncBothFriendRequest(ctx, tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) - case constant.FriendAddedNotification: - var tips sdkws.FriendAddedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.Friend != nil && tips.Friend.FriendUser != nil { - if tips.Friend.FriendUser.UserID == f.loginUserID { - return f.SyncFriends(ctx, []string{tips.Friend.OwnerUserID}) - } else if tips.Friend.OwnerUserID == f.loginUserID { - return f.SyncFriends(ctx, []string{tips.Friend.FriendUser.UserID}) - } - } - case constant.FriendDeletedNotification: - var tips sdkws.FriendDeletedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.FromToUserID != nil { - if tips.FromToUserID.FromUserID == f.loginUserID { - return f.deleteFriend(ctx, tips.FromToUserID.ToUserID) - } - } - case constant.FriendRemarkSetNotification: - var tips sdkws.FriendInfoChangedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.FromToUserID != nil { - if tips.FromToUserID.FromUserID == f.loginUserID { - return f.SyncFriends(ctx, []string{tips.FromToUserID.ToUserID}) - } - } - case constant.FriendInfoUpdatedNotification: - var tips sdkws.UserInfoUpdatedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.UserID != f.loginUserID { - return f.SyncFriends(ctx, []string{tips.UserID}) - } - case constant.BlackAddedNotification: - var tips sdkws.BlackAddedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.FromToUserID.FromUserID == f.loginUserID { - return f.SyncAllBlackList(ctx) - } - case constant.BlackDeletedNotification: - var tips sdkws.BlackDeletedTips - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.FromToUserID.FromUserID == f.loginUserID { - return f.SyncAllBlackList(ctx) - } - case constant.FriendsInfoUpdateNotification: - - var tips sdkws.FriendsInfoUpdateTips - - if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { - return err - } - if tips.FromToUserID.ToUserID == f.loginUserID { - return f.SyncFriends(ctx, tips.FriendIDs) - } - default: - return fmt.Errorf("type failed %d", msg.ContentType) - } - return nil -} diff --git a/internal/friend/notification.go b/internal/friend/notification.go index 54db0344c..743ecdc2d 100644 --- a/internal/friend/notification.go +++ b/internal/friend/notification.go @@ -13,3 +13,124 @@ // limitations under the License. package friend + +import ( + "context" + "fmt" + + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" + "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/log" +) + +func (f *Friend) DoNotification(ctx context.Context, msg *sdkws.MsgData) { + go func() { + if err := f.doNotification(ctx, msg); err != nil { + log.ZError(ctx, "doNotification error", err, "msg", msg) + } + }() +} + +func (f *Friend) doNotification(ctx context.Context, msg *sdkws.MsgData) error { + switch msg.ContentType { + case constant.FriendApplicationNotification: + tips := sdkws.FriendApplicationTips{} + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + return f.SyncBothFriendRequest(ctx, + tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) + case constant.FriendApplicationApprovedNotification: + var tips sdkws.FriendApplicationApprovedTips + err := utils.UnmarshalNotificationElem(msg.Content, &tips) + if err != nil { + return err + } + + if tips.FromToUserID.FromUserID == f.loginUserID { + err = f.SyncFriends(ctx, []string{tips.FromToUserID.ToUserID}) + } else if tips.FromToUserID.ToUserID == f.loginUserID { + err = f.SyncFriends(ctx, []string{tips.FromToUserID.FromUserID}) + } + if err != nil { + return err + } + return f.SyncBothFriendRequest(ctx, tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) + case constant.FriendApplicationRejectedNotification: + var tips sdkws.FriendApplicationRejectedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + return f.SyncBothFriendRequest(ctx, tips.FromToUserID.FromUserID, tips.FromToUserID.ToUserID) + case constant.FriendAddedNotification: + var tips sdkws.FriendAddedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.Friend != nil && tips.Friend.FriendUser != nil { + if tips.Friend.FriendUser.UserID == f.loginUserID { + return f.SyncFriends(ctx, []string{tips.Friend.OwnerUserID}) + } else if tips.Friend.OwnerUserID == f.loginUserID { + return f.SyncFriends(ctx, []string{tips.Friend.FriendUser.UserID}) + } + } + case constant.FriendDeletedNotification: + var tips sdkws.FriendDeletedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.FromToUserID != nil { + if tips.FromToUserID.FromUserID == f.loginUserID { + return f.deleteFriend(ctx, tips.FromToUserID.ToUserID) + } + } + case constant.FriendRemarkSetNotification: + var tips sdkws.FriendInfoChangedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.FromToUserID != nil { + if tips.FromToUserID.FromUserID == f.loginUserID { + return f.SyncFriends(ctx, []string{tips.FromToUserID.ToUserID}) + } + } + case constant.FriendInfoUpdatedNotification: + var tips sdkws.UserInfoUpdatedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.UserID != f.loginUserID { + return f.SyncFriends(ctx, []string{tips.UserID}) + } + case constant.BlackAddedNotification: + var tips sdkws.BlackAddedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.FromToUserID.FromUserID == f.loginUserID { + return f.SyncAllBlackList(ctx) + } + case constant.BlackDeletedNotification: + var tips sdkws.BlackDeletedTips + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.FromToUserID.FromUserID == f.loginUserID { + return f.SyncAllBlackList(ctx) + } + case constant.FriendsInfoUpdateNotification: + + var tips sdkws.FriendsInfoUpdateTips + + if err := utils.UnmarshalNotificationElem(msg.Content, &tips); err != nil { + return err + } + if tips.FromToUserID.ToUserID == f.loginUserID { + return f.SyncFriends(ctx, tips.FriendIDs) + } + default: + return fmt.Errorf("type failed %d", msg.ContentType) + } + return nil +} diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index 42c39fc0a..9353b7427 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -16,11 +16,12 @@ package interaction import ( "context" + "strings" + "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" - "strings" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" @@ -76,6 +77,7 @@ func (m *MsgSyncer) loadSeq(ctx context.Context) error { if len(conversationIDList) == 0 { m.reinstalled = true } + //TODO have a 9s performance problem when login. for _, v := range conversationIDList { maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, v) if err != nil { diff --git a/open_im_sdk/group.go b/open_im_sdk/group.go index 41d3ae680..0ff9b0fe7 100644 --- a/open_im_sdk/group.go +++ b/open_im_sdk/group.go @@ -36,41 +36,50 @@ func DismissGroup(callback open_im_sdk_callback.Base, operationID string, groupI call(callback, operationID, UserForSDK.Group().DismissGroup, groupID) } -func SetGroupMemberRoleLevel(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, roleLevel int) { - call(callback, operationID, UserForSDK.Group().SetGroupMemberRoleLevel, groupID, userID, roleLevel) -} - func SetGroupVerification(callback open_im_sdk_callback.Base, operationID string, groupID string, verification int32) { call(callback, operationID, UserForSDK.Group().SetGroupVerification, groupID, verification) } + func SetGroupApplyMemberFriend(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { call(callback, operationID, UserForSDK.Group().SetGroupApplyMemberFriend, groupID, rule) } -func ChangeGroupMute(callback open_im_sdk_callback.Base, operationID string, groupID string, isMute bool) { - call(callback, operationID, UserForSDK.Group().ChangeGroupMute, groupID, isMute) +func SetGroupLookMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { + call(callback, operationID, UserForSDK.Group().SetGroupLookMemberInfo, groupID, rule) } -func SetGroupInfo(callback open_im_sdk_callback.Base, operationID string, groupInfo string) { - call(callback, operationID, UserForSDK.Group().SetGroupInfo, groupInfo) +func ChangeGroupMute(callback open_im_sdk_callback.Base, operationID string, groupID string, isMute bool) { + call(callback, operationID, UserForSDK.Group().ChangeGroupMute, groupID, isMute) } -func KickGroupMember(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { - call(callback, operationID, UserForSDK.Group().KickGroupMember, groupID, reason, userIDList) +func ChangeGroupMemberMute(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, mutedSeconds int) { + call(callback, operationID, UserForSDK.Group().ChangeGroupMemberMute, groupID, userID, mutedSeconds) } func TransferGroupOwner(callback open_im_sdk_callback.Base, operationID string, groupID string, newOwnerUserID string) { call(callback, operationID, UserForSDK.Group().TransferGroupOwner, groupID, newOwnerUserID) } -func ChangeGroupMemberMute(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, mutedSeconds int) { - call(callback, operationID, UserForSDK.Group().ChangeGroupMemberMute, groupID, userID, mutedSeconds) +func KickGroupMember(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) { + call(callback, operationID, UserForSDK.Group().KickGroupMember, groupID, reason, userIDList) +} + +func SetGroupInfo(callback open_im_sdk_callback.Base, operationID string, groupInfo string) { + call(callback, operationID, UserForSDK.Group().SetGroupInfo, groupInfo) } func SetGroupMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupMemberInfo string) { call(callback, operationID, UserForSDK.Group().SetGroupMemberInfo, groupMemberInfo) } +func SetGroupMemberRoleLevel(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, roleLevel int) { + call(callback, operationID, UserForSDK.Group().SetGroupMemberRoleLevel, groupID, userID, roleLevel) +} + +func SetGroupMemberNickname(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, groupMemberNickname string) { + call(callback, operationID, UserForSDK.Group().SetGroupMemberNickname, groupID, userID, groupMemberNickname) +} + func GetJoinedGroupList(callback open_im_sdk_callback.Base, operationID string) { call(callback, operationID, UserForSDK.Group().GetJoinedGroupList) } @@ -83,10 +92,6 @@ func SearchGroups(callback open_im_sdk_callback.Base, operationID string, search call(callback, operationID, UserForSDK.Group().SearchGroups, searchParam) } -func SetGroupLookMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) { - call(callback, operationID, UserForSDK.Group().SetGroupLookMemberInfo, groupID, rule) -} - func GetGroupMemberOwnerAndAdmin(callback open_im_sdk_callback.Base, operationID string, groupID string) { call(callback, operationID, UserForSDK.Group().GetGroupMemberOwnerAndAdmin, groupID) } @@ -130,7 +135,3 @@ func AcceptGroupApplication(callback open_im_sdk_callback.Base, operationID stri func RefuseGroupApplication(callback open_im_sdk_callback.Base, operationID string, groupID string, fromUserID string, handleMsg string) { call(callback, operationID, UserForSDK.Group().RefuseGroupApplication, groupID, fromUserID, handleMsg) } - -func SetGroupMemberNickname(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, groupMemberNickname string) { - call(callback, operationID, UserForSDK.Group().SetGroupMemberNickname, groupID, userID, groupMemberNickname) -} From 5de091730e54ba21c5b2e40fa6c503d021f2f408 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 18:45:47 +0800 Subject: [PATCH 31/69] update --- internal/group/sdk.go | 70 ++++++------------------------------------- 1 file changed, 9 insertions(+), 61 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index ad8f3101f..d8b1cadc5 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -121,9 +121,6 @@ func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { return err } @@ -151,40 +148,6 @@ func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.S return g.IncrSyncGroupAndMember(ctx, groupMemberInfo.GroupID) } -func (g *Group) TransferGroupOwner(ctx context.Context, groupID, newOwnerUserID string) error { - if err := util.ApiPost(ctx, constant.TransferGroupRouter, &group.TransferGroupOwnerReq{GroupID: groupID, OldOwnerUserID: g.loginUserID, NewOwnerUserID: newOwnerUserID}, nil); err != nil { - return err - } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } - if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { - return err - } - return nil -} - -func (g *Group) KickGroupMember(ctx context.Context, groupID string, reason string, userIDList []string) error { - if err := util.ApiPost(ctx, constant.KickGroupMemberRouter, &group.KickGroupMemberReq{GroupID: groupID, KickedUserIDs: userIDList, Reason: reason}, nil); err != nil { - return err - } - return g.IncrSyncGroupAndMember(ctx, groupID) -} - -func (g *Group) IncrSyncGroupAndMember(ctx context.Context, groupInfo *sdkws.GroupInfoForSet) error { - if err := util.ApiPost(ctx, constant.SetGroupInfoRouter, &group.SetGroupInfoReq{GroupInfoForSet: groupInfo}, nil); err != nil { - return err - } - return g.IncrSyncJoinGroup(ctx) -} - -func (g *Group) SetGroupMemberInfo(ctx context.Context, groupMemberInfo *group.SetGroupMemberInfo) error { - if err := util.ApiPost(ctx, constant.SetGroupMemberInfoRouter, &group.SetGroupMemberInfoReq{Members: []*group.SetGroupMemberInfo{groupMemberInfo}}, nil); err != nil { - return err - } - return g.IncrSyncGroupAndMember(ctx, groupMemberInfo.GroupID) -} - func (g *Group) SetGroupMemberRoleLevel(ctx context.Context, groupID, userID string, roleLevel int) error { return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, RoleLevel: wrapperspb.Int32(int32(roleLevel))}) } @@ -266,30 +229,15 @@ func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.Sear // }) // } -func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { - dataFetcher := datafetcher.NewDataFetcher( - g.db, - g.groupAndMemberVersionTableName(), - groupID, - func(localGroupMember *model_struct.LocalGroupMember) string { - return localGroupMember.UserID - }, - func(ctx context.Context, values []*model_struct.LocalGroupMember) error { - return g.db.BatchInsertGroupMember(ctx, values) - }, - func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { - return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) - }, - func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { - serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) - if err != nil { - return nil, err - } - return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil - }, - ) - return dataFetcher.FetchMissingAndFillLocal(ctx, userIDList) - // return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) +func (g *Group) GetGroupMemberOwnerAndAdmin(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberOwnerAndAdminDB(ctx, groupID) +} + +func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID string, offset, count int32, joinTimeBegin, joinTimeEnd int64, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + if joinTimeEnd == 0 { + joinTimeEnd = time.Now().UnixMilli() + } + return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) } func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { From ecc079bacca4488028a54a6541c2bf5f1de005cf Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 18:53:07 +0800 Subject: [PATCH 32/69] update --- internal/group/sdk.go | 4 +--- internal/incrversion/option.go | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index d8b1cadc5..3cddb762e 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -319,9 +319,7 @@ func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, u if err := util.ApiPost(ctx, constant.InviteUserToGroupRouter, &group.InviteUserToGroupReq{GroupID: groupID, Reason: reason, InvitedUserIDs: userIDList}, nil); err != nil { return err } - if err := g.IncrSyncJoinGroup(ctx); err != nil { - return err - } + if err := g.IncrSyncGroupAndMember(ctx, groupID); err != nil { return err } diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index 947c0683d..b27f462e0 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -161,7 +161,6 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TableName, "entityID", o.EntityID) return nil } - log.ZDebug(o.Ctx, "check version sync", "table", o.TableName, "entityID", o.EntityID, "versionID", versionID, "localVersionID", lvs.VersionID, "version", version, "localVersion", lvs.Version) /// If the version unique ID cannot correspond with the local version, // it indicates that the data might have been tampered with or an exception has occurred. //Trigger the complete client-server incremental synchronization. From 4f30965996627b1c50b23d5694455c0947082694 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Thu, 20 Jun 2024 18:57:30 +0800 Subject: [PATCH 33/69] update contents. --- internal/incrversion/option.go | 2 +- internal/interaction/msg_sync.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index b27f462e0..e666a1aa9 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -85,7 +85,6 @@ func (o *VersionSynchronizer[V, R]) Sync() error { extraData = temp } } - log.ZDebug(o.Ctx, "Sync panic", "changes", changes, "insert", insert, "delIDs", delIDs) if len(delIDs) == 0 && len(changes) == 0 && len(insert) == 0 && !o.Full(resp) && extraData == nil { log.ZDebug(o.Ctx, "no data to sync", "table", o.TableName, "entityID", o.EntityID) return nil @@ -161,6 +160,7 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { log.ZWarn(o.Ctx, "exception no data to sync", errs.New("notification no data"), "table", o.TableName, "entityID", o.EntityID) return nil } + log.ZDebug(o.Ctx, "check version sync", "table", o.TableName, "entityID", o.EntityID, "versionID", versionID, "localVersionID", lvs.VersionID, "version", version, "localVersion", lvs.Version) /// If the version unique ID cannot correspond with the local version, // it indicates that the data might have been tampered with or an exception has occurred. //Trigger the complete client-server incremental synchronization. diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index 9353b7427..43475b716 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -77,7 +77,7 @@ func (m *MsgSyncer) loadSeq(ctx context.Context) error { if len(conversationIDList) == 0 { m.reinstalled = true } - //TODO have a 9s performance problem when login. + //TODO With a large number of sessions, this could potentially cause blocking and needs optimization. for _, v := range conversationIDList { maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, v) if err != nil { From 9538aefe8fc49fd185b44a3de198a1cd84208c3e Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:59:03 +0800 Subject: [PATCH 34/69] feat: friend full sync and incr sync. --- .../conversation_notification.go | 40 +++++++++---- internal/conversation_msg/read_drawing.go | 19 ------ internal/group/sync.go | 59 +++++++++---------- 3 files changed, 56 insertions(+), 62 deletions(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 82039376a..73cdf8ecf 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -17,12 +17,15 @@ package conversation_msg import ( "context" "encoding/json" + "fmt" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "github.com/openimsdk/tools/utils/datautil" + "reflect" + "runtime" "time" "github.com/openimsdk/protocol/sdkws" @@ -59,19 +62,30 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } //clear SubscriptionStatusMap c.user.OnlineStatusCache.DeleteAll() - //for _, syncFunc := range []func(c context.Context) error{ - // c.user.SyncLoginUserInfo, - // c.friend.SyncAllBlackList, c.friend.SyncAllFriendList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, - // c.group.SyncAllJoinedGroupsAndMembers, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, - //} { - // go func(syncFunc func(c context.Context) error) { - // _ = syncFunc(ctx) - // }(syncFunc) - //} - c.group.SyncAllJoinedGroupsAndMembers2(ctx) - err := c.friend.SyncAllFriendList(ctx) - if err != nil { - log.ZError(ctx, "SyncAllFriendList err", err) + for _, asyncFunc := range []func(c context.Context) error{ + c.user.SyncLoginUserInfo, + c.friend.SyncAllBlackList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, + c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, + } { + go func(asyncFunc func(c context.Context) error) { + _ = asyncFunc(ctx) + }(asyncFunc) + } + + syncFunctions := []func(c context.Context) error{ + c.group.SyncAllJoinedGroupsAndMembers, c.friend.IncrSyncFriends, + } + + for _, syncFunc := range syncFunctions { + funcName := runtime.FuncForPC(reflect.ValueOf(syncFunc).Pointer()).Name() + startTime := time.Now() + err := syncFunc(ctx) + duration := time.Since(startTime) + if err != nil { + log.ZWarn(ctx, fmt.Sprintf("%s sync err", funcName), err, "duration", duration) + } else { + log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration) + } } case constant.MsgSyncFailed: c.ConversationListener().OnSyncServerFailed() diff --git a/internal/conversation_msg/read_drawing.go b/internal/conversation_msg/read_drawing.go index 6b96d3147..4ec825dbf 100644 --- a/internal/conversation_msg/read_drawing.go +++ b/internal/conversation_msg/read_drawing.go @@ -275,25 +275,6 @@ func (c *Conversation) doReadDrawing(ctx context.Context, msg *sdkws.MsgData) { SessionType: conversation.ConversationType, ReadTime: msg.SendTime}} c.msgListener().OnRecvC2CReadReceipt(utils.StructToJsonString(messageReceiptResp)) } - //else if conversation.ConversationType == constant.SuperGroupChatType { - // var successMsgIDs []string - // for _, message := range messages { - // attachInfo := sdk_struct.AttachedInfoElem{} - // _ = utils.JsonStringToStruct(message.AttachedInfo, &attachInfo) - // attachInfo.HasReadTime = msg.SendTime - // attachInfo.GroupHasReadInfo.HasReadUserIDList = utils.RemoveRepeatedStringInList(append(attachInfo.GroupHasReadInfo.HasReadUserIDList, tips.MarkAsReadUserID)) - // attachInfo.GroupHasReadInfo.HasReadCount = int32(len(attachInfo.GroupHasReadInfo.HasReadUserIDList)) - // message.AttachedInfo = utils.StructToJsonString(attachInfo) - // if err = c.db.UpdateMessage(ctx, tips.ConversationID, message); err != nil { - // log.ZError(ctx, "UpdateMessage err", err, "conversationID", tips.ConversationID, "message", message) - // } else { - // successMsgIDs = append(successMsgIDs, message.ClientMsgID) - // } - // } - // var messageReceiptResp = []*sdk_struct.MessageReceipt{{GroupID: conversation.GroupID, MsgIDList: successMsgIDs, - // SessionType: conversation.ConversationType, ReadTime: msg.SendTime}} - // c.msgListener.OnRecvGroupReadReceipt(utils.StructToJsonString(messageReceiptResp)) - //} } else { c.doUnreadCount(ctx, conversation, tips.HasReadSeq, tips.Seqs) } diff --git a/internal/group/sync.go b/internal/group/sync.go index ff3ed1040..16b338cdf 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -28,7 +28,6 @@ import ( "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" - "sync" "time" ) @@ -173,6 +172,35 @@ func (g *Group) deleteGroup(ctx context.Context, groupID string) error { //return nil } +// func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { +// t := time.Now() +// defer func(start time.Time) { +// +// elapsed := time.Since(start).Milliseconds() +// log.ZDebug(ctx, "SyncAllJoinedGroupsAndMembers fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) +// +// }(t) +// _, err := g.syncAllJoinedGroups(ctx) +// if err != nil { +// return err +// } +// groups, err := g.db.GetJoinedGroupListDB(ctx) +// if err != nil { +// return err +// } +// var wg sync.WaitGroup +// for _, group := range groups { +// wg.Add(1) +// go func(groupID string) { +// defer wg.Done() +// if err := g.SyncAllGroupMember(ctx, groupID); err != nil { +// log.ZError(ctx, "SyncGroupMember failed", err) +// } +// }(group.GroupID) +// } +// wg.Wait() +// return nil +// } func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { t := time.Now() defer func(start time.Time) { @@ -180,35 +208,6 @@ func (g *Group) SyncAllJoinedGroupsAndMembers(ctx context.Context) error { elapsed := time.Since(start).Milliseconds() log.ZDebug(ctx, "SyncAllJoinedGroupsAndMembers fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) - }(t) - _, err := g.syncAllJoinedGroups(ctx) - if err != nil { - return err - } - groups, err := g.db.GetJoinedGroupListDB(ctx) - if err != nil { - return err - } - var wg sync.WaitGroup - for _, group := range groups { - wg.Add(1) - go func(groupID string) { - defer wg.Done() - if err := g.SyncAllGroupMember(ctx, groupID); err != nil { - log.ZError(ctx, "SyncGroupMember failed", err) - } - }(group.GroupID) - } - wg.Wait() - return nil -} -func (g *Group) SyncAllJoinedGroupsAndMembers2(ctx context.Context) error { - t := time.Now() - defer func(start time.Time) { - - elapsed := time.Since(start).Milliseconds() - log.ZDebug(ctx, "SyncAllJoinedGroupsAndMembers fn call end", "cost time", fmt.Sprintf("%d ms", elapsed)) - }(t) if err := g.IncrSyncJoinGroup(ctx); err != nil { return err From cd07f0788eeaa1f6e80dc65ff4b413795597e58d Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:47:23 +0800 Subject: [PATCH 35/69] fix: sync log change avoid printing repeat output. --- pkg/syncer/syncer.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index d4c5acdae..000319b23 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -20,6 +20,7 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/page" "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" "reflect" "github.com/openimsdk/tools/log" @@ -253,10 +254,9 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData } // Convert local data into a map for easier lookup. - localMap := make(map[V]T) - for i, item := range localData { - localMap[s.uuid(item)] = localData[i] - } + localMap := datautil.SliceToMap(localData, func(item T) V { + return s.uuid(item) + }) // Iterate through server data to sync with local data. for i := range serverData { @@ -266,6 +266,7 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData // If the item doesn't exist locally, insert it. if !ok { + log.ZDebug(ctx, "sync insert", "type", s.ts, "server", server) if err := s.insert(ctx, server); err != nil { log.ZError(ctx, "sync insert failed", err, "type", s.ts, "server", server, "local", local) return err @@ -279,7 +280,6 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData // Remove the item from the local map as it's found. delete(localMap, id) - log.ZDebug(ctx, "syncer come", "type", s.ts, "server", server, "local", local, "isEq", s.eq(server, local)) // If the local and server items are equal, notify and continue. if s.eq(server, local) { @@ -290,6 +290,7 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData continue } + log.ZDebug(ctx, "sync update", "type", s.ts, "server", server, "local", local) // Update the local item with server data. if err := s.update(ctx, server, local); err != nil { log.ZError(ctx, "sync update failed", err, "type", s.ts, "server", server, "local", local) @@ -305,7 +306,7 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData if skipDeletion { return nil } - + log.ZDebug(ctx, "sync delete", "type", s.ts, "localMap", localMap) // Delete any local items not present in server data. for id := range localMap { local := localMap[id] From 53e91b06eb2212191f812a8460b277502863ebac Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Fri, 21 Jun 2024 10:54:25 +0800 Subject: [PATCH 36/69] fix log error implement. --- pkg/db/db_init.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/db/db_init.go b/pkg/db/db_init.go index 8641d3072..6f64d5b95 100644 --- a/pkg/db/db_init.go +++ b/pkg/db/db_init.go @@ -148,7 +148,6 @@ func (d *DataBase) initDB(ctx context.Context, logLevel int) error { func (d *DataBase) versionDataMigrate(ctx context.Context) error { verModel, err := d.GetAppSDKVersion(ctx) - log.ZDebug(ctx, "SDK err is", errs.Unwrap(err)) if errs.Unwrap(err) == gorm.ErrRecordNotFound { err = d.conn.AutoMigrate( &model_struct.LocalAppSDKVersion{}, From 0fbd5f86ecc539e130aceb6c1ea738394d2fe4fd Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 21 Jun 2024 11:42:19 +0800 Subject: [PATCH 37/69] fix: sync log change avoid printing repeat output. --- internal/group/group.go | 2 +- internal/group/sync2.go | 5 +++-- pkg/syncer/syncer.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/group/group.go b/internal/group/group.go index 6574f3d9e..115d36847 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -129,7 +129,7 @@ func (g *Group) initSyncer() { }), syncer.WithBatchPageReq[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(entityID string) page.PageReq { return &group.GetJoinedGroupListReq{FromUserID: entityID, - Pagination: &sdkws.RequestPagination{}} + Pagination: &sdkws.RequestPagination{ShowNumber: 100}} }), syncer.WithBatchPageRespConvertFunc[*model_struct.LocalGroup, group.GetJoinedGroupListResp, string](func(resp *group.GetJoinedGroupListResp) []*model_struct.LocalGroup { return datautil.Batch(ServerGroupToLocalGroup, resp.Groups) diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 71d7d530a..159588081 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -2,6 +2,7 @@ package group import ( "context" + "gorm.io/gorm" "sync" "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" @@ -79,8 +80,8 @@ func (g *Group) IncrSyncGroupAndMember(ctx context.Context, groupIDs ...string) if err == nil { req.VersionID = lvs.VersionID req.Version = lvs.Version - } else { - log.ZInfo(ctx, "get group version", "groupID", groupID, "error", err) + } else if errs.Unwrap(err) != gorm.ErrRecordNotFound { + return err } groups = append(groups, &req) } diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index 000319b23..d002276f5 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -349,7 +349,7 @@ func (s *Syncer[T, RESP, V]) FullSync(ctx context.Context, entityID string) (err // Batch page pull data and insert server data if err = util.FetchAndInsertPagedData(ctx, s.reqApiRouter, batchReq, s.batchPageRespConvertFunc, - s.batchInsert, s.insert, 10000); err != nil { + s.batchInsert, s.insert, 100); err != nil { return errs.New("full sync batch insert failed", "err", err.Error(), "type", s.ts) } From 59400b4d48fc7ec21ce16fe90cb289f86e4175b7 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Fri, 21 Jun 2024 15:49:10 +0800 Subject: [PATCH 38/69] fix uncorrect variable call. --- internal/incrversion/option.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index e666a1aa9..50b43ea4e 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -184,7 +184,8 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { kv := datautil.SliceToMapAny(local, func(v V) (string, V) { return o.Key(v), v }) - for i, change := range append(changes, insert...) { + changes = append(changes, insert...) + for i, change := range changes { key := o.Key(change) kv[key] = changes[i] } From 68f0e1809c3928184c8cabf4abbde7dc174d4dc1 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Fri, 21 Jun 2024 15:50:47 +0800 Subject: [PATCH 39/69] fix uncorrect log use. --- test/t_conversation_msg.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/t_conversation_msg.go b/test/t_conversation_msg.go index 57e877070..c0d1373f3 100644 --- a/test/t_conversation_msg.go +++ b/test/t_conversation_msg.go @@ -17,6 +17,8 @@ package test import ( "encoding/json" "fmt" + "sync" + "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" @@ -24,7 +26,6 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "github.com/openimsdk/tools/log" - "sync" "github.com/openimsdk/protocol/sdkws" @@ -670,7 +671,7 @@ func (c *conversationCallBack) OnNewConversation(conversationList string) { } func (c *conversationCallBack) OnConversationChanged(conversationList string) { - log.ZInfo(ctx, "OnConversationChanged returnList is", conversationList) + log.ZInfo(ctx, "OnConversationChanged. ", "returnList is", conversationList) } func (c *conversationCallBack) OnTotalUnreadMessageCountChanged(totalUnreadCount int32) { From 25fa892157ae8f29ca3064a38ce1767d2ac6ee9d Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Sat, 22 Jun 2024 17:55:29 +0800 Subject: [PATCH 40/69] fix uncorrect name. --- internal/group/sync2.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 159588081..a64a26c8b 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -2,14 +2,15 @@ package group import ( "context" - "gorm.io/gorm" "sync" + "gorm.io/gorm" + "github.com/openimsdk/openim-sdk-core/v3/internal/incrversion" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - pconstant "github.com/openimsdk/protocol/constant" + constantpb "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" @@ -57,7 +58,7 @@ func (g *Group) IncrSyncGroupAndMember(ctx context.Context, groupIDs ...string) if len(groupIDs) == 0 { return nil } - const maxSyncNum = pconstant.MaxSyncPullNumber + const maxSyncNum = constantpb.MaxSyncPullNumber groupIDSet := datautil.SliceSet(groupIDs) var groups []*group.GetIncrementalGroupMemberReq if len(groupIDs) > maxSyncNum { From ff4e7497ec61dd0c32922c88c6403b5c570ed6b7 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Sat, 22 Jun 2024 17:57:44 +0800 Subject: [PATCH 41/69] refactor: optimize Error call and unnecessary data conversion. --- pkg/db/admin_group_request_model.go | 24 ++++---- pkg/db/black_model.go | 43 +++++--------- pkg/db/chat_log_model_v3.go | 66 +++++++++++---------- pkg/db/friend_model.go | 54 +++++------------ pkg/db/friend_request_model.go | 38 ++++-------- pkg/db/group_member_model.go | 91 ++++++++++------------------- pkg/db/group_model.go | 46 +++++---------- pkg/db/group_request_model.go | 24 +++----- 8 files changed, 140 insertions(+), 246 deletions(-) diff --git a/pkg/db/admin_group_request_model.go b/pkg/db/admin_group_request_model.go index 263123d6b..54d554efe 100644 --- a/pkg/db/admin_group_request_model.go +++ b/pkg/db/admin_group_request_model.go @@ -20,20 +20,21 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertAdminGroupRequest failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertAdminGroupRequest failed") } func (d *DataBase) DeleteAdminGroupRequest(ctx context.Context, groupID, userID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalAdminGroupRequest{}).Error, "DeleteAdminGroupRequest failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalAdminGroupRequest{}).Error, "DeleteAdminGroupRequest failed") } func (d *DataBase) UpdateAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error { @@ -41,23 +42,18 @@ func (d *DataBase) UpdateAdminGroupRequest(ctx context.Context, groupRequest *mo defer d.groupMtx.Unlock() t := d.conn.WithContext(ctx).Model(groupRequest).Select("*").Updates(*groupRequest) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.Wrap(t.Error) } func (d *DataBase) GetAdminGroupApplication(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupRequestList []model_struct.LocalAdminGroupRequest - err := utils.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error, "") + var groupRequestList []*model_struct.LocalAdminGroupRequest + err := errs.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error) if err != nil { - return nil, utils.Wrap(err, "") - } - var transfer []*model_struct.LocalAdminGroupRequest - for _, v := range groupRequestList { - v1 := v - transfer = append(transfer, &v1) + return nil, errs.Wrap(err) } - return transfer, nil + return groupRequestList, nil } diff --git a/pkg/db/black_model.go b/pkg/db/black_model.go index 363b78f6f..41e3ad9eb 100644 --- a/pkg/db/black_model.go +++ b/pkg/db/black_model.go @@ -20,61 +20,46 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetBlackListDB(ctx context.Context) ([]*model_struct.LocalBlack, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - if d == nil { - return nil, errors.New("database is not open") - } - var blackList []model_struct.LocalBlack - - err := d.conn.WithContext(ctx).Find(&blackList).Error - var transfer []*model_struct.LocalBlack - for _, v := range blackList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err + var blackList []*model_struct.LocalBlack + return blackList, errs.Wrap(d.conn.WithContext(ctx).Find(&blackList).Error) } func (d *DataBase) GetBlackListUserID(ctx context.Context) (blackListUid []string, err error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return blackListUid, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalBlack{}).Select("block_user_id").Find(&blackListUid).Error, "GetBlackList failed") + return blackListUid, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalBlack{}).Select("block_user_id").Find(&blackListUid).Error, "GetBlackList failed") } func (d *DataBase) GetBlackInfoByBlockUserID(ctx context.Context, blockUserID string) (*model_struct.LocalBlack, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() var black model_struct.LocalBlack - return &black, utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id = ? AND block_user_id = ? ", + return &black, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ? AND block_user_id = ? ", d.loginUserID, blockUserID).Take(&black).Error, "GetBlackInfoByBlockUserID failed") } func (d *DataBase) GetBlackInfoList(ctx context.Context, blockUserIDList []string) ([]*model_struct.LocalBlack, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var blackList []model_struct.LocalBlack - if t := d.conn.WithContext(ctx).Where("block_user_id IN ? ", blockUserIDList).Find(&blackList).Error; t != nil { - return nil, utils.Wrap(t, "GetBlackInfoList failed") - } - - var transfer []*model_struct.LocalBlack - for _, v := range blackList { - v1 := v - transfer = append(transfer, &v1) + var blackList []*model_struct.LocalBlack + if err := d.conn.WithContext(ctx).Where("block_user_id IN ? ", blockUserIDList).Find(&blackList).Error; err != nil { + return nil, errs.WrapMsg(err, "GetBlackInfoList failed") } - return transfer, nil + return blackList, nil } func (d *DataBase) InsertBlack(ctx context.Context, black *model_struct.LocalBlack) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(black).Error, "InsertBlack failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(black).Error, "InsertBlack failed") } func (d *DataBase) UpdateBlack(ctx context.Context, black *model_struct.LocalBlack) error { @@ -82,13 +67,13 @@ func (d *DataBase) UpdateBlack(ctx context.Context, black *model_struct.LocalBla defer d.friendMtx.Unlock() t := d.conn.WithContext(ctx).Updates(black) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateBlack failed") + return errs.WrapMsg(t.Error, "UpdateBlack failed") } func (d *DataBase) DeleteBlack(ctx context.Context, blockUserID string) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id=? and block_user_id=?", d.loginUserID, blockUserID).Delete(&model_struct.LocalBlack{}).Error, "DeleteBlack failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id=? and block_user_id=?", d.loginUserID, blockUserID).Delete(&model_struct.LocalBlack{}).Error, "DeleteBlack failed") } diff --git a/pkg/db/chat_log_model_v3.go b/pkg/db/chat_log_model_v3.go index 043cc6c05..da69c056a 100644 --- a/pkg/db/chat_log_model_v3.go +++ b/pkg/db/chat_log_model_v3.go @@ -21,11 +21,13 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" ) @@ -47,15 +49,15 @@ func (d *DataBase) initChatLog(ctx context.Context, conversationID string) { func (d *DataBase) UpdateMessage(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error { t := d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update ") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update ") } - return utils.Wrap(t.Error, "UpdateMessage failed") + return errs.WrapMsg(t.Error, "UpdateMessage failed") } func (d *DataBase) UpdateMessageBySeq(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq=?", c.Seq).Updates(c).Error, "UpdateMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq=?", c.Seq).Updates(c).Error, "UpdateMessage failed") } func (d *DataBase) BatchInsertMessageList(ctx context.Context, conversationID string, MessageList []*model_struct.LocalChatLog) error { @@ -64,32 +66,32 @@ func (d *DataBase) BatchInsertMessageList(ctx context.Context, conversationID st } d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(MessageList).Error, "BatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(MessageList).Error, "BatchInsertMessageList failed") } func (d *DataBase) InsertMessage(ctx context.Context, conversationID string, Message *model_struct.LocalChatLog) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(Message).Error, "InsertMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(Message).Error, "InsertMessage failed") } func (d *DataBase) GetMessage(ctx context.Context, conversationID string, clientMsgID string) (*model_struct.LocalChatLog, error) { d.initChatLog(ctx, conversationID) var c model_struct.LocalChatLog - return &c, utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id = ?", clientMsgID).Take(&c).Error, "GetMessage failed") } func (d *DataBase) GetMessageBySeq(ctx context.Context, conversationID string, seq int64) (*model_struct.LocalChatLog, error) { d.initChatLog(ctx, conversationID) var c model_struct.LocalChatLog - return &c, utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq = ?", seq).Take(&c).Error, "GetMessage failed") } func (d *DataBase) UpdateMessageTimeAndStatus(ctx context.Context, conversationID, clientMsgID string, serverMsgID string, sendTime int64, status int32) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where("client_msg_id=? And seq=?", clientMsgID, 0). + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where("client_msg_id=? And seq=?", clientMsgID, 0). Updates(model_struct.LocalChatLog{Status: status, SendTime: sendTime, ServerMsgID: serverMsgID}).Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) GetMessageListNoTime(ctx context.Context, conversationID string, @@ -103,7 +105,7 @@ func (d *DataBase) GetMessageListNoTime(ctx context.Context, conversationID stri } else { timeOrder = "send_time DESC" } - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Order(timeOrder).Offset(0).Limit(count).Find(&result).Error, "GetMessageList failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Order(timeOrder).Offset(0).Limit(count).Find(&result).Error, "GetMessageList failed") if err != nil { return nil, err } @@ -122,7 +124,7 @@ func (d *DataBase) GetMessageList(ctx context.Context, conversationID string, co } condition = "send_time " + timeSymbol + " ?" - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, startTime). + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, startTime). Order(timeOrder).Offset(0).Limit(count).Find(&result).Error, "GetMessageList failed") if err != nil { return nil, err @@ -133,30 +135,30 @@ func (d *DataBase) GetMessageList(ctx context.Context, conversationID string, co func (d *DataBase) DeleteConversationAllMessages(ctx context.Context, conversationID string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationAllMessages failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationAllMessages failed") } func (d *DataBase) MarkDeleteConversationAllMessages(ctx context.Context, conversationID string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Updates(model_struct.LocalChatLog{Status: constant.MsgStatusHasDeleted}).Error, "DeleteConversationAllMessages failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Updates(model_struct.LocalChatLog{Status: constant.MsgStatusHasDeleted}).Error, "DeleteConversationAllMessages failed") } func (d *DataBase) DeleteConversationMsgs(ctx context.Context, conversationID string, msgIDs []string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed") } func (d *DataBase) DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq IN ?", seqs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq IN ?", seqs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed") } func (d *DataBase) SearchMessageByContentType(ctx context.Context, contentType []int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) { condition := fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ?", startTime, endTime, constant.MsgStatusSendFailed) - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "SearchMessage failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "SearchMessage failed") return result, err } func (d *DataBase) SearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) { @@ -188,7 +190,7 @@ func (d *DataBase) SearchMessageByKeyword(ctx context.Context, contentType []int } condition = fmt.Sprintf(" send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed) condition += subCondition - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "InsertMessage failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "InsertMessage failed") return result, err } // SearchMessageByContentTypeAndKeyword searches for messages in the database that match specified content types and keywords within a given time range. func (d *DataBase) SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) { @@ -227,13 +229,13 @@ func (d *DataBase) SearchMessageByContentTypeAndKeyword(ctx context.Context, con condition += subCondition // Execute the query using the constructed condition and handle errors - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Find(&result).Error, "SearchMessage failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Find(&result).Error, "SearchMessage failed") return result, err } func (d *DataBase) UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, conversationID, sendID, faceURL, nickname string) error { - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where( "send_id = ?", sendID).Updates( map[string]interface{}{"sender_face_url": faceURL, "sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed") } @@ -241,7 +243,7 @@ func (d *DataBase) UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, func (d *DataBase) GetAlreadyExistSeqList(ctx context.Context, conversationID string, lostSeqList []int64) (seqList []int64, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", lostSeqList).Pluck("seq", &seqList).Error, utils.GetSelfFuncName()+" failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", lostSeqList).Pluck("seq", &seqList).Error, utils.GetSelfFuncName()+" failed") if err != nil { return nil, err } @@ -254,9 +256,9 @@ func (d *DataBase) UpdateColumnsMessage(ctx context.Context, conversationID, Cli c := model_struct.LocalChatLog{ClientMsgID: ClientMsgID} t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Model(&c).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } func (d *DataBase) SearchAllMessageByContentType(ctx context.Context, conversationID string, contentType int) (result []*model_struct.LocalChatLog, err error) { err = d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(&model_struct.LocalChatLog{}).Where("content_type = ?", contentType).Find(&result).Error @@ -265,7 +267,7 @@ func (d *DataBase) SearchAllMessageByContentType(ctx context.Context, conversati func (d *DataBase) GetUnreadMessage(ctx context.Context, conversationID string) (msgs []*model_struct.LocalChatLog, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Debug().Where("send_id != ? AND is_read = ?", d.loginUserID, constant.NotRead).Find(&msgs).Error, "GetMessageList failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Debug().Where("send_id != ? AND is_read = ?", d.loginUserID, constant.NotRead).Find(&msgs).Error, "GetMessageList failed") return msgs, err } @@ -274,9 +276,9 @@ func (d *DataBase) MarkConversationMessageAsReadBySeqs(ctx context.Context, conv defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq in ? AND send_id != ?", seqs, d.loginUserID).Update("is_read", constant.HasRead) if t.RowsAffected == 0 { - return 0, utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return t.RowsAffected, utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return t.RowsAffected, errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) MarkConversationMessageAsReadDB(ctx context.Context, conversationID string, msgIDs []string) (rowsAffected int64, err error) { @@ -284,7 +286,7 @@ func (d *DataBase) MarkConversationMessageAsReadDB(ctx context.Context, conversa defer d.mRWMutex.Unlock() var msgs []*model_struct.LocalChatLog if err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id in ? AND send_id != ?", msgIDs, d.loginUserID).Find(&msgs).Error; err != nil { - return 0, utils.Wrap(err, "MarkConversationMessageAsReadDB failed") + return 0, errs.WrapMsg(err, "MarkConversationMessageAsReadDB failed") } for _, msg := range msgs { var attachedInfo sdk_struct.AttachedInfoElem @@ -300,7 +302,7 @@ func (d *DataBase) MarkConversationMessageAsReadDB(ctx context.Context, conversa } // t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id in ? AND send_id != ?", msgIDs, d.loginUserID).Update("is_read", constant.HasRead) // if t.RowsAffected == 0 { - // return 0, utils.Wrap(errors.New("RowsAffected == 0"), "no update") + // return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") // } return rowsAffected, nil } @@ -310,18 +312,18 @@ func (d *DataBase) MarkConversationAllMessageAsRead(ctx context.Context, convers defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("send_id != ? AND is_read == ?", d.loginUserID, false).Update("is_read", constant.HasRead) if t.RowsAffected == 0 { - return 0, utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return t.RowsAffected, utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return t.RowsAffected, errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) GetMessagesByClientMsgIDs(ctx context.Context, conversationID string, msgIDs []string) (msgs []*model_struct.LocalChatLog, err error) { - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesByClientMsgIDs error") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesByClientMsgIDs error") return msgs, err } func (d *DataBase) GetMessagesBySeqs(ctx context.Context, conversationID string, seqs []int64) (msgs []*model_struct.LocalChatLog, err error) { - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", seqs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesBySeqs error") + err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", seqs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesBySeqs error") return msgs, err } @@ -329,11 +331,11 @@ func (d *DataBase) GetConversationNormalMsgSeq(ctx context.Context, conversation d.initChatLog(ctx, conversationID) var seq int64 err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Select("IFNULL(max(seq),0)").Find(&seq).Error - return seq, utils.Wrap(err, "GetConversationNormalMsgSeq") + return seq, errs.WrapMsg(err, "GetConversationNormalMsgSeq") } func (d *DataBase) GetConversationPeerNormalMsgSeq(ctx context.Context, conversationID string) (int64, error) { var seq int64 err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Select("IFNULL(max(seq),0)").Where("send_id != ?", d.loginUserID).Find(&seq).Error - return seq, utils.Wrap(err, "GetConversationPeerNormalMsgSeq") + return seq, errs.WrapMsg(err, "GetConversationPeerNormalMsgSeq") } diff --git a/pkg/db/friend_model.go b/pkg/db/friend_model.go index 6da7fd3de..f43c6382c 100644 --- a/pkg/db/friend_model.go +++ b/pkg/db/friend_model.go @@ -21,31 +21,30 @@ import ( "context" "errors" "fmt" + "gorm.io/gorm" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertFriend(ctx context.Context, friend *model_struct.LocalFriend) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(friend).Error, "InsertFriend failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(friend).Error, "InsertFriend failed") } func (d *DataBase) DeleteFriendDB(ctx context.Context, friendUserID string) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id=? and friend_user_id=?", d.loginUserID, friendUserID).Delete(&model_struct.LocalFriend{}).Error, "DeleteFriend failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id=? and friend_user_id=?", d.loginUserID, friendUserID).Delete(&model_struct.LocalFriend{}).Error, "DeleteFriend failed") } func (d *DataBase) GetFriendListCount(ctx context.Context) (int64, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() var count int64 - err := d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Count(&count).Error - return count, utils.Wrap(err, "GetFriendListCount failed") + return count, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Count(&count).Error, "GetFriendListCount failed") } func (d *DataBase) UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error { @@ -54,30 +53,24 @@ func (d *DataBase) UpdateFriend(ctx context.Context, friend *model_struct.LocalF t := d.conn.WithContext(ctx).Model(friend).Select("*").Updates(*friend) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.Wrap(t.Error) } func (d *DataBase) GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var friendList []model_struct.LocalFriend - err := utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Find(&friendList).Error, + var friendList []*model_struct.LocalFriend + return friendList, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Find(&friendList).Error, "GetFriendList failed") - var transfer []*model_struct.LocalFriend - for _, v := range friendList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err } func (d *DataBase) GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() var friendList []*model_struct.LocalFriend - err := utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Offset(offset).Limit(count).Order("name").Find(&friendList).Error, + err := errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Offset(offset).Limit(count).Order("name").Find(&friendList).Error, "GetFriendList failed") return friendList, err } @@ -101,7 +94,7 @@ func (d *DataBase) SearchFriendList(ctx context.Context, keyword string, isSearc d.friendMtx.Lock() defer d.friendMtx.Unlock() var count int - var friendList []model_struct.LocalFriend + var friendList []*model_struct.LocalFriend var condition string if isSearchUserID { condition = fmt.Sprintf("friend_user_id like %q ", "%"+keyword+"%") @@ -121,41 +114,26 @@ func (d *DataBase) SearchFriendList(ctx context.Context, keyword string, isSearc condition += fmt.Sprintf("remark like %q ", "%"+keyword+"%") } err := d.conn.WithContext(ctx).Where(condition).Order("create_time DESC").Find(&friendList).Error - var transfer []*model_struct.LocalFriend - for _, v := range friendList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "SearchFriendList failed ") - + return friendList, errs.WrapMsg(err, "SearchFriendList failed") } func (d *DataBase) GetFriendInfoByFriendUserID(ctx context.Context, FriendUserID string) (*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() var friend model_struct.LocalFriend - return &friend, utils.Wrap(d.conn.WithContext(ctx).Where("owner_user_id = ? AND friend_user_id = ?", + return &friend, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ? AND friend_user_id = ?", d.loginUserID, FriendUserID).Take(&friend).Error, "GetFriendInfoByFriendUserID failed") } func (d *DataBase) GetFriendInfoList(ctx context.Context, friendUserIDList []string) ([]*model_struct.LocalFriend, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var friendList []model_struct.LocalFriend - err := utils.Wrap(d.conn.WithContext(ctx).Where("friend_user_id IN ?", friendUserIDList).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed") - var transfer []*model_struct.LocalFriend - for _, v := range friendList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err + var friendList []*model_struct.LocalFriend + err := errs.WrapMsg(d.conn.WithContext(ctx).Where("friend_user_id IN ?", friendUserIDList).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed") + return friendList, err } func (d *DataBase) UpdateColumnsFriend(ctx context.Context, friendIDs []string, args map[string]interface{}) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - - // Update records where FriendUserID is in the friendIDs slice - t := d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Where("friend_user_id IN ?", friendIDs).Updates(args) - - return utils.Wrap(t.Error, "UpdateColumnsFriend failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Where("friend_user_id IN ?", friendIDs).Updates(args).Error, "UpdateColumnsFriend failed") } diff --git a/pkg/db/friend_request_model.go b/pkg/db/friend_request_model.go index a9620e012..2bf0dbbb6 100644 --- a/pkg/db/friend_request_model.go +++ b/pkg/db/friend_request_model.go @@ -20,20 +20,21 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(friendRequest).Error, "InsertFriendRequest failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(friendRequest).Error, "InsertFriendRequest failed") } func (d *DataBase) DeleteFriendRequestBothUserID(ctx context.Context, fromUserID, toUserID string) error { d.friendMtx.Lock() defer d.friendMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("from_user_id=? and to_user_id=?", fromUserID, toUserID).Delete(&model_struct.LocalFriendRequest{}).Error, "DeleteFriendRequestBothUserID failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id=? and to_user_id=?", fromUserID, toUserID).Delete(&model_struct.LocalFriendRequest{}).Error, "DeleteFriendRequestBothUserID failed") } func (d *DataBase) UpdateFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error { @@ -41,50 +42,35 @@ func (d *DataBase) UpdateFriendRequest(ctx context.Context, friendRequest *model defer d.friendMtx.Unlock() t := d.conn.WithContext(ctx).Model(friendRequest).Select("*").Updates(*friendRequest) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.Wrap(t.Error) } func (d *DataBase) GetRecvFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var friendRequestList []model_struct.LocalFriendRequest - err := utils.Wrap(d.conn.WithContext(ctx).Where("to_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetRecvFriendApplication failed") + var friendRequestList []*model_struct.LocalFriendRequest - var transfer []*model_struct.LocalFriendRequest - for _, v := range friendRequestList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetRecvFriendApplication failed") + return friendRequestList, errs.WrapMsg(d.conn.WithContext(ctx).Where("to_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetRecvFriendApplication failed") } func (d *DataBase) GetSendFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var friendRequestList []model_struct.LocalFriendRequest - err := utils.Wrap(d.conn.WithContext(ctx).Where("from_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetSendFriendApplication failed") - - var transfer []*model_struct.LocalFriendRequest - for _, v := range friendRequestList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetSendFriendApplication failed") + var friendRequestList []*model_struct.LocalFriendRequest + return friendRequestList, errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetSendFriendApplication failed") } func (d *DataBase) GetFriendApplicationByBothID(ctx context.Context, fromUserID, toUserID string) (*model_struct.LocalFriendRequest, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() var friendRequest model_struct.LocalFriendRequest - err := utils.Wrap(d.conn.WithContext(ctx).Where("from_user_id = ? AND to_user_id = ?", fromUserID, toUserID).Take(&friendRequest).Error, "GetFriendApplicationByBothID failed") - return &friendRequest, utils.Wrap(err, "GetFriendApplicationByBothID failed") + return &friendRequest, errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id = ? AND to_user_id = ?", fromUserID, toUserID).Take(&friendRequest).Error, "GetFriendApplicationByBothID failed") } func (d *DataBase) GetBothFriendReq(ctx context.Context, fromUserID, toUserID string) (friendRequests []*model_struct.LocalFriendRequest, err error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - err = utils.Wrap(d.conn.WithContext(ctx).Where("(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)", fromUserID, toUserID, toUserID, fromUserID).Find(&friendRequests).Error, "GetFriendApplicationByBothID failed") - return friendRequests, utils.Wrap(err, "GetFriendApplicationByBothID failed") + return friendRequests, errs.WrapMsg(d.conn.WithContext(ctx).Where("(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)", fromUserID, toUserID, toUserID, fromUserID).Find(&friendRequests).Error, "GetFriendApplicationByBothID failed") } diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 218056c3b..4af2ba374 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -24,7 +24,6 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/tools/errs" ) @@ -32,7 +31,7 @@ func (d *DataBase) GetGroupMemberInfoByGroupIDUserID(ctx context.Context, groupI d.groupMtx.Lock() defer d.groupMtx.Unlock() var groupMember model_struct.LocalGroupMember - return &groupMember, utils.Wrap(d.conn.WithContext(ctx).Where("group_id = ? AND user_id = ?", + return &groupMember, errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id = ? AND user_id = ?", groupID, userID).Take(&groupMember).Error, "GetGroupMemberInfoByGroupIDUserID failed") } @@ -40,13 +39,13 @@ func (d *DataBase) GetAllGroupMemberList(ctx context.Context) ([]model_struct.Lo d.groupMtx.Lock() defer d.groupMtx.Unlock() var groupMemberList []model_struct.LocalGroupMember - return groupMemberList, utils.Wrap(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed") + return groupMemberList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed") } func (d *DataBase) GetAllGroupMemberUserIDList(ctx context.Context) ([]model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() var groupMemberList []model_struct.LocalGroupMember - return groupMemberList, utils.Wrap(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed") + return groupMemberList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed") } func (d *DataBase) GetGroupMemberCount(ctx context.Context, groupID string) (int32, error) { @@ -54,39 +53,29 @@ func (d *DataBase) GetGroupMemberCount(ctx context.Context, groupID string) (int defer d.groupMtx.Unlock() var count int64 err := d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Where("group_id = ? ", groupID).Count(&count).Error - return int32(count), utils.Wrap(err, "GetGroupMemberCount failed") + return int32(count), errs.WrapMsg(err, "GetGroupMemberCount failed") } func (d *DataBase) GetGroupSomeMemberInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember err := d.conn.WithContext(ctx).Where("group_id = ? And user_id IN ? ", groupID, userIDList).Find(&groupMemberList).Error - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListByGroupID failed ") + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ") } func (d *DataBase) GetGroupAdminID(ctx context.Context, groupID string) ([]string, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() var adminIDList []string - return adminIDList, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Select("user_id").Where("group_id = ? And role_level = ?", groupID, constant.GroupAdmin).Find(&adminIDList).Error, "") + return adminIDList, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Select("user_id").Where("group_id = ? And role_level = ?", groupID, constant.GroupAdmin).Find(&adminIDList).Error, "") } func (d *DataBase) GetGroupMemberListByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember err := d.conn.WithContext(ctx).Where("group_id = ? ", groupID).Find(&groupMemberList).Error - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListByGroupID failed ") + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ") } func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error) { @@ -118,7 +107,7 @@ func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID stri func (d *DataBase) GetGroupMemberListSplit(ctx context.Context, groupID string, filter int32, offset, count int) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember var err error switch filter { case constant.GroupFilterAll: @@ -136,25 +125,17 @@ func (d *DataBase) GetGroupMemberListSplit(ctx context.Context, groupID string, default: return nil, errs.New("filter args failed", "filter", filter).Wrap() } - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListSplit failed ") + + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplit failed ") } func (d *DataBase) GetGroupMemberOwnerAndAdminDB(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember err := d.conn.WithContext(ctx).Where("group_id = ? And (role_level = ? OR role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Order("join_time DESC").Find(&groupMemberList).Error - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListSplit failed ") + + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplit failed ") } func (d *DataBase) GetGroupMemberOwner(ctx context.Context, groupID string) (*model_struct.LocalGroupMember, error) { @@ -162,38 +143,28 @@ func (d *DataBase) GetGroupMemberOwner(ctx context.Context, groupID string) (*mo defer d.groupMtx.Unlock() var groupMember model_struct.LocalGroupMember err := d.conn.WithContext(ctx).Where("group_id = ? And role_level = ?", groupID, constant.GroupOwner).Find(&groupMember).Error - return &groupMember, utils.Wrap(err, "GetGroupMemberListSplit failed ") + return &groupMember, errs.WrapMsg(err, "GetGroupMemberListSplit failed ") } func (d *DataBase) GetGroupMemberListSplitByJoinTimeFilter(ctx context.Context, groupID string, offset, count int, joinTimeBegin, joinTimeEnd int64, userIDList []string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember var err error if len(userIDList) == 0 { err = d.conn.WithContext(ctx).Where("group_id = ? And join_time between ? and ? ", groupID, joinTimeBegin, joinTimeEnd).Order("join_time DESC").Offset(offset).Limit(count).Find(&groupMemberList).Error } else { err = d.conn.WithContext(ctx).Where("group_id = ? And join_time between ? and ? And user_id NOT IN ?", groupID, joinTimeBegin, joinTimeEnd, userIDList).Order("join_time DESC").Offset(offset).Limit(count).Find(&groupMemberList).Error } - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListSplitByJoinTimeFilter failed ") + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplitByJoinTimeFilter failed ") } func (d *DataBase) GetGroupOwnerAndAdminByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupMemberList []model_struct.LocalGroupMember + var groupMemberList []*model_struct.LocalGroupMember err := d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? Or role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Find(&groupMemberList).Error - var transfer []*model_struct.LocalGroupMember - for _, v := range groupMemberList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroupMemberListByGroupID failed ") + return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ") } func (d *DataBase) GetGroupMemberUIDListByGroupID(ctx context.Context, groupID string) (result []string, err error) { @@ -202,13 +173,13 @@ func (d *DataBase) GetGroupMemberUIDListByGroupID(ctx context.Context, groupID s var g model_struct.LocalGroupMember g.GroupID = groupID err = d.conn.WithContext(ctx).Model(&g).Where("group_id = ?", groupID).Pluck("user_id", &result).Error - return result, utils.Wrap(err, "GetGroupMemberListByGroupID failed ") + return result, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ") } func (d *DataBase) InsertGroupMember(ctx context.Context, groupMember *model_struct.LocalGroupMember) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(groupMember).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMember).Error, "") } //funcation (d *DataBase) BatchInsertMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error { @@ -217,7 +188,7 @@ func (d *DataBase) InsertGroupMember(ctx context.Context, groupMember *model_str // } // d.mRWMutex.Lock() // defer d.mRWMutex.Unlock() -// return utils.Wrap(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertMessageList failed") +// return errs.WrapMsg(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertMessageList failed") //} func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList []*model_struct.LocalGroupMember) error { @@ -232,14 +203,14 @@ func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList [ func (d *DataBase) DeleteGroupMember(ctx context.Context, groupID, userID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - groupMember := model_struct.LocalGroupMember{} + var groupMember model_struct.LocalGroupMember return d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&groupMember).Error } func (d *DataBase) DeleteGroupAllMembers(ctx context.Context, groupID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - groupMember := model_struct.LocalGroupMember{} + var groupMember model_struct.LocalGroupMember return d.conn.WithContext(ctx).Where("group_id=? ", groupID).Delete(&groupMember).Error } @@ -248,9 +219,9 @@ func (d *DataBase) UpdateGroupMember(ctx context.Context, groupMember *model_str defer d.groupMtx.Unlock() t := d.conn.WithContext(ctx).Model(groupMember).Select("*").Updates(*groupMember) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.WrapMsg(t.Error, "") } func (d *DataBase) UpdateGroupMemberField(ctx context.Context, groupID, userID string, args map[string]interface{}) error { @@ -259,21 +230,21 @@ func (d *DataBase) UpdateGroupMemberField(ctx context.Context, groupID, userID s c := model_struct.LocalGroupMember{GroupID: groupID, UserID: userID} t := d.conn.WithContext(ctx).Model(&c).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateGroupMemberField failed") + return errs.WrapMsg(t.Error, "UpdateGroupMemberField failed") } func (d *DataBase) GetGroupMemberInfoIfOwnerOrAdmin(ctx context.Context) ([]*model_struct.LocalGroupMember, error) { var ownerAndAdminList []*model_struct.LocalGroupMember groupList, err := d.GetJoinedGroupListDB(ctx) if err != nil { - return nil, utils.Wrap(err, "") + return nil, errs.Wrap(err) } for _, v := range groupList { memberList, err := d.GetGroupOwnerAndAdminByGroupID(ctx, v.GroupID) if err != nil { - return nil, utils.Wrap(err, "") + return nil, errs.Wrap(err) } ownerAndAdminList = append(ownerAndAdminList, memberList...) } diff --git a/pkg/db/group_model.go b/pkg/db/group_model.go index 42ab308fe..4153c2674 100644 --- a/pkg/db/group_model.go +++ b/pkg/db/group_model.go @@ -21,8 +21,8 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/tools/errs" "gorm.io/gorm" @@ -31,13 +31,13 @@ import ( func (d *DataBase) InsertGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(groupInfo).Error, "InsertGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupInfo).Error, "InsertGroup failed") } func (d *DataBase) DeleteGroup(ctx context.Context, groupID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() localGroup := model_struct.LocalGroup{GroupID: groupID} - return utils.Wrap(d.conn.WithContext(ctx).Delete(&localGroup).Error, "DeleteGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Delete(&localGroup).Error, "DeleteGroup failed") } func (d *DataBase) UpdateGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error { d.groupMtx.Lock() @@ -45,15 +45,14 @@ func (d *DataBase) UpdateGroup(ctx context.Context, groupInfo *model_struct.Loca t := d.conn.WithContext(ctx).Model(groupInfo).Select("*").Updates(*groupInfo) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") - + return errs.Wrap(t.Error) } func (d *DataBase) BatchInsertGroup(ctx context.Context, groupList []*model_struct.LocalGroup) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(groupList).Error, "BatchInsertGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupList).Error, "BatchInsertGroup failed") } func (d *DataBase) DeleteAllGroup(ctx context.Context) error { @@ -65,40 +64,30 @@ func (d *DataBase) DeleteAllGroup(ctx context.Context) error { func (d *DataBase) GetJoinedGroupListDB(ctx context.Context) ([]*model_struct.LocalGroup, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupList []model_struct.LocalGroup + var groupList []*model_struct.LocalGroup err := d.conn.WithContext(ctx).Find(&groupList).Error - var transfer []*model_struct.LocalGroup - for _, v := range groupList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetJoinedGroupList failed ") + return groupList, errs.WrapMsg(err, "GetJoinedGroupList failed ") } func (d *DataBase) GetGroups(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupList []model_struct.LocalGroup + var groupList []*model_struct.LocalGroup err := d.conn.WithContext(ctx).Where("group_id in (?)", groupIDs).Find(&groupList).Error - var transfer []*model_struct.LocalGroup - for _, v := range groupList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetGroups failed ") + return groupList, errs.WrapMsg(err, "GetGroups failed ") } func (d *DataBase) GetGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() var g model_struct.LocalGroup - return &g, utils.Wrap(d.conn.WithContext(ctx).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed") + return &g, errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed") } func (d *DataBase) GetAllGroupInfoByGroupIDOrGroupName(ctx context.Context, keyword string, isSearchGroupID bool, isSearchGroupName bool) ([]*model_struct.LocalGroup, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupList []model_struct.LocalGroup + var groupList []*model_struct.LocalGroup var condition string if isSearchGroupID { if isSearchGroupName { @@ -110,24 +99,19 @@ func (d *DataBase) GetAllGroupInfoByGroupIDOrGroupName(ctx context.Context, keyw condition = fmt.Sprintf("name like %q ", "%"+keyword+"%") } err := d.conn.WithContext(ctx).Where(condition).Order("create_time DESC").Find(&groupList).Error - var transfer []*model_struct.LocalGroup - for _, v := range groupList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, utils.Wrap(err, "GetAllGroupInfoByGroupIDOrGroupName failed ") + return groupList, errs.WrapMsg(err, "GetAllGroupInfoByGroupIDOrGroupName failed ") } func (d *DataBase) AddMemberCount(ctx context.Context, groupID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() group := model_struct.LocalGroup{GroupID: groupID} - return utils.Wrap(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count+1")}).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count+1")}).Error, "") } func (d *DataBase) SubtractMemberCount(ctx context.Context, groupID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() group := model_struct.LocalGroup{GroupID: groupID} - return utils.Wrap(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count-1")}).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count-1")}).Error, "") } diff --git a/pkg/db/group_request_model.go b/pkg/db/group_request_model.go index 4e90b3e8d..856175f0b 100644 --- a/pkg/db/group_request_model.go +++ b/pkg/db/group_request_model.go @@ -20,42 +20,34 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertGroupRequest failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertGroupRequest failed") } func (d *DataBase) DeleteGroupRequest(ctx context.Context, groupID, userID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalGroupRequest{}).Error, "DeleteGroupRequest failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalGroupRequest{}).Error, "DeleteGroupRequest failed") } func (d *DataBase) UpdateGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() t := d.conn.WithContext(ctx).Model(groupRequest).Select("*").Updates(*groupRequest) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.Wrap(t.Error) } func (d *DataBase) GetSendGroupApplication(ctx context.Context) ([]*model_struct.LocalGroupRequest, error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() - var groupRequestList []model_struct.LocalGroupRequest - err := utils.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error, "") - if err != nil { - return nil, utils.Wrap(err, "") - } - var transfer []*model_struct.LocalGroupRequest - for _, v := range groupRequestList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, nil + var groupRequestList []*model_struct.LocalGroupRequest + return groupRequestList, errs.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error) } From c8bc179ca152c24d23b7575269fea231224fb4d7 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 10:22:14 +0800 Subject: [PATCH 42/69] update SpecifiedFriends Info data fetch implements. --- internal/friend/sdk.go | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index 4f5b417c7..ee7f671dc 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -17,6 +17,11 @@ package friend import ( "context" + friend "github.com/openimsdk/protocol/relation" + "github.com/openimsdk/protocol/wrapperspb" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/utils/datautil" + "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" @@ -24,19 +29,37 @@ import ( sdk "github.com/openimsdk/openim-sdk-core/v3/pkg/sdk_params_callback" "github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs" "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" - friend "github.com/openimsdk/protocol/relation" - "github.com/openimsdk/protocol/wrapperspb" - "github.com/openimsdk/tools/errs" - "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/log" ) func (f *Friend) GetSpecifiedFriendsInfo(ctx context.Context, friendUserIDList []string) ([]*server_api_params.FullUserInfo, error) { - localFriendList, err := f.db.GetFriendInfoList(ctx, friendUserIDList) + datafetcher := datafetcher.NewDataFetcher( + f.db, + f.friendListTableName(), + f.loginUserID, + func(localFriend *model_struct.LocalFriend) string { + return localFriend.FriendUserID + }, + func(ctx context.Context, values []*model_struct.LocalFriend) error { + return f.db.BatchInsertFriend(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + return f.db.GetFriendInfoList(ctx, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + serverFriend, err := f.GetDesignatedFriends(ctx, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerFriendToLocalFriend, serverFriend), nil + }, + ) + localFriendList, err := datafetcher.FetchMissingAndFillLocal(ctx, friendUserIDList) if err != nil { return nil, err } + log.ZDebug(ctx, "GetDesignatedFriendsInfo", "localFriendList", localFriendList) blackList, err := f.db.GetBlackInfoList(ctx, friendUserIDList) if err != nil { @@ -85,7 +108,6 @@ func (f *Friend) RefuseFriendApplication(ctx context.Context, userIDHandleMsg *s } func (f *Friend) RespondFriendApply(ctx context.Context, req *friend.RespondFriendApplyReq) error { - if req.ToUserID == "" { req.ToUserID = f.loginUserID } @@ -97,7 +119,7 @@ func (f *Friend) RespondFriendApply(ctx context.Context, req *friend.RespondFrie } _ = f.SyncAllFriendApplication(ctx) return nil - //return f.SyncFriendApplication(ctx) + // return f.SyncFriendApplication(ctx) } func (f *Friend) CheckFriend(ctx context.Context, friendUserIDList []string) ([]*server_api_params.UserIDResult, error) { @@ -261,6 +283,7 @@ func (f *Friend) PinFriends(ctx context.Context, friends *sdk.SetFriendPinParams } return f.SyncFriends(ctx, friends.ToUserIDs) } + func (f *Friend) AddBlack(ctx context.Context, blackUserID string, ex string) error { if err := util.ApiPost(ctx, constant.AddBlackRouter, &friend.AddBlackReq{OwnerUserID: f.loginUserID, BlackUserID: blackUserID, Ex: ex}, nil); err != nil { return err @@ -278,6 +301,7 @@ func (f *Friend) RemoveBlack(ctx context.Context, blackUserID string) error { func (f *Friend) GetBlackList(ctx context.Context) ([]*model_struct.LocalBlack, error) { return f.db.GetBlackListDB(ctx) } + func (f *Friend) SetFriendsEx(ctx context.Context, friendIDs []string, ex string) error { if err := util.ApiPost(ctx, constant.UpdateFriends, &friend.UpdateFriendsReq{OwnerUserID: f.loginUserID, FriendUserIDs: friendIDs, Ex: &wrapperspb.StringValue{ Value: ex, From ccf908a36c5fbf306c54559137a4a535c3232bcc Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:20:16 +0800 Subject: [PATCH 43/69] feat: get group list add page function. --- internal/conversation_msg/conversation_notification.go | 8 ++++---- internal/group/sdk.go | 6 +++++- open_im_sdk/group.go | 4 ++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 73cdf8ecf..2c8392683 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -62,14 +62,14 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } //clear SubscriptionStatusMap c.user.OnlineStatusCache.DeleteAll() - for _, asyncFunc := range []func(c context.Context) error{ + for _, syncFunc := range []func(c context.Context) error{ c.user.SyncLoginUserInfo, c.friend.SyncAllBlackList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, } { - go func(asyncFunc func(c context.Context) error) { - _ = asyncFunc(ctx) - }(asyncFunc) + go func(syncFunc func(c context.Context) error) { + _ = syncFunc(ctx) + }(syncFunc) } syncFunctions := []func(c context.Context) error{ diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 3cddb762e..e52851d94 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -156,7 +156,11 @@ func (g *Group) SetGroupMemberNickname(ctx context.Context, groupID, userID stri return g.SetGroupMemberInfo(ctx, &group.SetGroupMemberInfo{GroupID: groupID, UserID: userID, Nickname: wrapperspb.String(groupMemberNickname)}) } -func (g *Group) GetJoinedGroupList(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, error) { +func (g *Group) GetJoinedGroupList(ctx context.Context) ([]*model_struct.LocalGroup, error) { + return g.db.GetJoinedGroupListDB(ctx) +} + +func (g *Group) GetJoinedGroupListPage(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupTableName(), diff --git a/open_im_sdk/group.go b/open_im_sdk/group.go index 0ff9b0fe7..691c3dd0e 100644 --- a/open_im_sdk/group.go +++ b/open_im_sdk/group.go @@ -84,6 +84,10 @@ func GetJoinedGroupList(callback open_im_sdk_callback.Base, operationID string) call(callback, operationID, UserForSDK.Group().GetJoinedGroupList) } +func GetJoinedGroupListPage(callback open_im_sdk_callback.Base, operationID string, offset, count int32) { + call(callback, operationID, UserForSDK.Group().GetJoinedGroupListPage, offset, count) +} + func GetSpecifiedGroupsInfo(callback open_im_sdk_callback.Base, operationID string, groupIDList string) { call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupsInfo, groupIDList) } From 36979e745c7f5815452fb5ed51e4f4a064ee85f7 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 14:43:14 +0800 Subject: [PATCH 44/69] feat: crate new FetchPagination With IsEnd is general method. --- pkg/datafetcher/datafetcher.go | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go index cb7972ba9..939d62970 100644 --- a/pkg/datafetcher/datafetcher.go +++ b/pkg/datafetcher/datafetcher.go @@ -96,3 +96,60 @@ func (ds *DataFetcher[T]) FetchMissingAndFillLocal(ctx context.Context, uids []s return localData, nil } + +func (ds *DataFetcher[T]) FetchWithPaginationV2(ctx context.Context, offset, limit int) ([]T, bool, error) { + var isEnd bool + versionInfo, err := ds.db.GetVersionSync(ctx, ds.TableName, ds.EntityID) + if err != nil { + return nil, isEnd, err + } + + if offset > len(versionInfo.UIDList) { + return nil, isEnd, errs.New("offset exceeds the length of the UID list").Wrap() + } + + end := offset + limit + if end >= len(versionInfo.UIDList) { + isEnd = true + end = len(versionInfo.UIDList) + } + + paginatedUIDs := versionInfo.UIDList[offset:end] + + localData, isEnd, err := ds.FetchMissingAndFillLocalV2(ctx, paginatedUIDs, isEnd) + if err != nil { + return nil, isEnd, err + } + return localData, isEnd, nil +} + +func (ds *DataFetcher[T]) FetchMissingAndFillLocalV2(ctx context.Context, uids []string, isEnd bool) ([]T, bool, error) { + localData, err := ds.FetchFromLocal(ctx, uids) + if err != nil { + return nil, isEnd, err + } + + localUIDSet := datautil.SliceSetAny(localData, ds.Key) + + var missingUIDs []string + for _, uid := range uids { + if _, found := localUIDSet[uid]; !found { + missingUIDs = append(missingUIDs, uid) + } + } + + if len(missingUIDs) > 0 { + serverData, err := ds.fetchFromServer(ctx, missingUIDs) + if err != nil { + isEnd = false + } + + if err := ds.batchInsert(ctx, serverData); err != nil { + return nil, isEnd, err + } + + localData = append(localData, serverData...) + } + + return localData, isEnd, nil +} From 0c1c2debdececd3a9bdf1b110fc48dd627e667d5 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 15:06:08 +0800 Subject: [PATCH 45/69] update fetch implement contents --- pkg/datafetcher/datafetcher.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go index 939d62970..004fe255c 100644 --- a/pkg/datafetcher/datafetcher.go +++ b/pkg/datafetcher/datafetcher.go @@ -126,7 +126,7 @@ func (ds *DataFetcher[T]) FetchWithPaginationV2(ctx context.Context, offset, lim func (ds *DataFetcher[T]) FetchMissingAndFillLocalV2(ctx context.Context, uids []string, isEnd bool) ([]T, bool, error) { localData, err := ds.FetchFromLocal(ctx, uids) if err != nil { - return nil, isEnd, err + return nil, false, err } localUIDSet := datautil.SliceSetAny(localData, ds.Key) @@ -141,11 +141,11 @@ func (ds *DataFetcher[T]) FetchMissingAndFillLocalV2(ctx context.Context, uids [ if len(missingUIDs) > 0 { serverData, err := ds.fetchFromServer(ctx, missingUIDs) if err != nil { - isEnd = false + return localData, false, nil } if err := ds.batchInsert(ctx, serverData); err != nil { - return nil, isEnd, err + return nil, false, err } localData = append(localData, serverData...) From 8b7b464cae0a89a8fdc9164fb5f1cecd81199b32 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 16:43:13 +0800 Subject: [PATCH 46/69] implment is ListPage with isEnd. --- internal/group/sdk.go | 82 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index e52851d94..d244fde0f 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -21,6 +21,7 @@ import ( "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" + "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -210,6 +211,39 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( return dataFetcher.FetchMissingAndFillLocal(ctx, groupIDs) } +func (g *Group) GetJoinedGroupListPageV2(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, bool, error) { + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupTableName(), + g.loginUserID, + func(localGroup *model_struct.LocalGroup) string { + return localGroup.GroupID + }, + func(ctx context.Context, values []*model_struct.LocalGroup) error { + return g.db.BatchInsertGroup(ctx, values) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + return g.db.GetGroups(ctx, groupIDs) + }, + func(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) { + serverGroupInfo, err := g.getGroupsInfoFromSvr(ctx, groupIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupToLocalGroup, serverGroupInfo), nil + }, + ) + + // for _, groupMember := range groupMemberList { + // resp=append(resp, &sdk_struct.GroupListWithIsEnd{ + // GroupID: groupMember.GroupID, + // GroupName: string, + // Notification: groupMember, + // }) + // } + return dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) +} + func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.SearchGroupsParam) ([]*model_struct.LocalGroup, error) { if len(param.KeywordList) == 0 || (!param.IsSearchGroupName && !param.IsSearchGroupID) { return nil, sdkerrs.ErrArgs.WrapMsg("keyword is null or search field all false") @@ -267,7 +301,6 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string }, ) return dataFetcher.FetchMissingAndFillLocal(ctx, userIDList) - // return g.db.GetGroupSomeMemberInfo(ctx, groupID, userIDList) } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { @@ -295,6 +328,53 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) } +func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) ([]*sdk_struct.GroupMemberListWithIsEnd, error) { + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupAndMemberVersionTableName(), + groupID, + func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListByUserIDs(ctx, groupID, filter, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil + }, + ) + groupMemberList, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + if err != nil { + return nil, err + } + resp := make([]*sdk_struct.GroupMemberListWithIsEnd, 0, len(groupMemberList)) + for _, groupMember := range groupMemberList { + resp = append(resp, &sdk_struct.GroupMemberListWithIsEnd{ + GroupID: groupMember.GroupID, + UserID: groupMember.UserID, + Nickname: groupMember.Nickname, + FaceURL: groupMember.FaceURL, + RoleLevel: groupMember.RoleLevel, + JoinTime: groupMember.JoinTime, + JoinSource: groupMember.JoinSource, + InviterUserID: groupMember.InviterUserID, + MuteEndTime: groupMember.MuteEndTime, + OperatorUserID: groupMember.OperatorUserID, + Ex: groupMember.Ex, + AttachedInfo: groupMember.AttachedInfo, + IsEnd: isEnd, + }) + } + return resp, nil +} + func (g *Group) GetGroupApplicationListAsRecipient(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { return g.db.GetAdminGroupApplication(ctx) } From 51d972b9eec8ff8d7e7364c69dfe3c34ab9c939a Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 16:44:13 +0800 Subject: [PATCH 47/69] implment struct include isEnd. --- sdk_struct/sdk_struct.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/sdk_struct/sdk_struct.go b/sdk_struct/sdk_struct.go index 3698854d7..b1627b945 100644 --- a/sdk_struct/sdk_struct.go +++ b/sdk_struct/sdk_struct.go @@ -364,3 +364,41 @@ type MsgDeleteNotificationElem struct { IsAllDelete bool `json:"isAllDelete"` SeqList []string `json:"seqList"` } + +type GroupListWithIsEnd struct { + GroupID string `json:"groupID"` + GroupName string `json:"groupName"` + Notification string `json:"notification"` + Introduction string `json:"introduction"` + FaceURL string `json:"faceURL"` + CreateTime int64 `json:"createTime"` + Status int32 `json:"status"` + CreatorUserID string `json:"creatorUserID"` + GroupType int32 `json:"groupType"` + OwnerUserID string `json:"ownerUserID"` + MemberCount int32 `json:"memberCount"` + Ex string `json:"ex"` + AttachedInfo string `json:"attachedInfo"` + NeedVerification int32 `json:"needVerification"` + LookMemberInfo int32 `json:"lookMemberInfo"` + ApplyMemberFriend int32 `json:"applyMemberFriend"` + NotificationUpdateTime int64 `json:"notificationUpdateTime"` + NotificationUserID string `json:"notificationUserID"` + IsEnd bool `json:"isEnd"` +} + +type GroupMemberListWithIsEnd struct { + GroupID string `json:"groupID"` + UserID string `json:"userID"` + Nickname string `json:"nickname"` + FaceURL string `json:"faceURL"` + RoleLevel int32 `json:"roleLevel"` + JoinTime int64 `json:"joinTime"` + JoinSource int32 `json:"joinSource"` + InviterUserID string `json:"inviterUserID"` + MuteEndTime int64 `json:"muteEndTime"` + OperatorUserID string `json:"operatorUserID"` + Ex string `json:"ex"` + AttachedInfo string `json:"attachedInfo"` + IsEnd bool `json:"isEnd"` +} From b39fd2eb9805d07b3f5eca2216a90a101ed8a0cd Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 17:02:46 +0800 Subject: [PATCH 48/69] fix resp struct to correct. --- internal/group/sdk.go | 29 +++++++---------------------- internal/group/types.go | 13 +++++++++++++ sdk_struct/sdk_struct.go | 37 ------------------------------------- 3 files changed, 20 insertions(+), 59 deletions(-) create mode 100644 internal/group/types.go diff --git a/internal/group/sdk.go b/internal/group/sdk.go index d244fde0f..fc7f36351 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -21,7 +21,6 @@ import ( "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/openim-sdk-core/v3/pkg/datafetcher" - "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" "github.com/openimsdk/openim-sdk-core/v3/internal/util" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -328,7 +327,7 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) } -func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) ([]*sdk_struct.GroupMemberListWithIsEnd, error) { +func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) (*GroupMemberListWithIsEnd, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupAndMemberVersionTableName(), @@ -350,29 +349,15 @@ func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil }, ) - groupMemberList, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + var groupMemberList *GroupMemberListWithIsEnd + groupMembers, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) if err != nil { return nil, err } - resp := make([]*sdk_struct.GroupMemberListWithIsEnd, 0, len(groupMemberList)) - for _, groupMember := range groupMemberList { - resp = append(resp, &sdk_struct.GroupMemberListWithIsEnd{ - GroupID: groupMember.GroupID, - UserID: groupMember.UserID, - Nickname: groupMember.Nickname, - FaceURL: groupMember.FaceURL, - RoleLevel: groupMember.RoleLevel, - JoinTime: groupMember.JoinTime, - JoinSource: groupMember.JoinSource, - InviterUserID: groupMember.InviterUserID, - MuteEndTime: groupMember.MuteEndTime, - OperatorUserID: groupMember.OperatorUserID, - Ex: groupMember.Ex, - AttachedInfo: groupMember.AttachedInfo, - IsEnd: isEnd, - }) - } - return resp, nil + groupMemberList.GroupMemberList = groupMembers + groupMemberList.IsEnd = isEnd + + return groupMemberList, nil } func (g *Group) GetGroupApplicationListAsRecipient(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { diff --git a/internal/group/types.go b/internal/group/types.go new file mode 100644 index 000000000..4275922ae --- /dev/null +++ b/internal/group/types.go @@ -0,0 +1,13 @@ +package group + +import "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + +type GroupMemberListWithIsEnd struct { + GroupMemberList []*model_struct.LocalGroupMember + IsEnd bool `json:"isEnd"` +} + +type GroupListWithIsEnd struct { + GroupList []*model_struct.LocalGroup + IsEnd bool `json:"isEnd"` +} diff --git a/sdk_struct/sdk_struct.go b/sdk_struct/sdk_struct.go index b1627b945..acd54a4d7 100644 --- a/sdk_struct/sdk_struct.go +++ b/sdk_struct/sdk_struct.go @@ -365,40 +365,3 @@ type MsgDeleteNotificationElem struct { SeqList []string `json:"seqList"` } -type GroupListWithIsEnd struct { - GroupID string `json:"groupID"` - GroupName string `json:"groupName"` - Notification string `json:"notification"` - Introduction string `json:"introduction"` - FaceURL string `json:"faceURL"` - CreateTime int64 `json:"createTime"` - Status int32 `json:"status"` - CreatorUserID string `json:"creatorUserID"` - GroupType int32 `json:"groupType"` - OwnerUserID string `json:"ownerUserID"` - MemberCount int32 `json:"memberCount"` - Ex string `json:"ex"` - AttachedInfo string `json:"attachedInfo"` - NeedVerification int32 `json:"needVerification"` - LookMemberInfo int32 `json:"lookMemberInfo"` - ApplyMemberFriend int32 `json:"applyMemberFriend"` - NotificationUpdateTime int64 `json:"notificationUpdateTime"` - NotificationUserID string `json:"notificationUserID"` - IsEnd bool `json:"isEnd"` -} - -type GroupMemberListWithIsEnd struct { - GroupID string `json:"groupID"` - UserID string `json:"userID"` - Nickname string `json:"nickname"` - FaceURL string `json:"faceURL"` - RoleLevel int32 `json:"roleLevel"` - JoinTime int64 `json:"joinTime"` - JoinSource int32 `json:"joinSource"` - InviterUserID string `json:"inviterUserID"` - MuteEndTime int64 `json:"muteEndTime"` - OperatorUserID string `json:"operatorUserID"` - Ex string `json:"ex"` - AttachedInfo string `json:"attachedInfo"` - IsEnd bool `json:"isEnd"` -} From b97b716ffc69c5ed3715a33c86b356a3daf58624 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 18:11:10 +0800 Subject: [PATCH 49/69] feat:implement GetListpagination without serverData error in group module. --- internal/group/sdk.go | 102 ++++++++++++++++++++++++++++++++-------- internal/group/sync2.go | 4 ++ internal/group/types.go | 12 ++--- 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index fc7f36351..6ae639eee 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -210,7 +210,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( return dataFetcher.FetchMissingAndFillLocal(ctx, groupIDs) } -func (g *Group) GetJoinedGroupListPageV2(ctx context.Context, offset, count int32) ([]*model_struct.LocalGroup, bool, error) { +func (g *Group) GetJoinedGroupListPageV2(ctx context.Context, offset, count int32) (*GetGroupListV2Response, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupTableName(), @@ -233,14 +233,16 @@ func (g *Group) GetJoinedGroupListPageV2(ctx context.Context, offset, count int3 }, ) - // for _, groupMember := range groupMemberList { - // resp=append(resp, &sdk_struct.GroupListWithIsEnd{ - // GroupID: groupMember.GroupID, - // GroupName: string, - // Notification: groupMember, - // }) - // } - return dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + groupsList, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + if err != nil { + return nil, err + } + + resp := &GetGroupListV2Response{ + GroupsList: groupsList, + IsEnd: isEnd, + } + return resp, nil } func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.SearchGroupsParam) ([]*model_struct.LocalGroup, error) { @@ -274,13 +276,74 @@ func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID if joinTimeEnd == 0 { joinTimeEnd = time.Now().UnixMilli() } - return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) + + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupMemberTableName(), + groupID, + func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil + }, + ) + + return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) +} + +func (g *Group) GetGroupMemberListByJoinTimeFilterV2(ctx context.Context, groupID string, offset, count int32, joinTimeBegin, joinTimeEnd int64, userIDs []string) (*GetGroupMemberListV2Response, error) { + if joinTimeEnd == 0 { + joinTimeEnd = time.Now().UnixMilli() + } + + dataFetcher := datafetcher.NewDataFetcher( + g.db, + g.groupMemberTableName(), + groupID, + func(localGroupMember *model_struct.LocalGroupMember) string { + return localGroupMember.UserID + }, + func(ctx context.Context, values []*model_struct.LocalGroupMember) error { + return g.db.BatchInsertGroupMember(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + return g.db.GetGroupMemberListSplitByJoinTimeFilter(ctx, groupID, int(offset), int(count), joinTimeBegin, joinTimeEnd, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalGroupMember, error) { + serverGroupMember, err := g.GetDesignatedGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil + }, + ) + + groupMembersList, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + if err != nil { + return nil, err + } + resp := &GetGroupMemberListV2Response{ + GroupMembersList: groupMembersList, + IsEnd: isEnd, + } + return resp, nil } func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupAndMemberVersionTableName(), + g.groupMemberTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -305,7 +368,7 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupAndMemberVersionTableName(), + g.groupMemberTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -327,10 +390,10 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, return dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) } -func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) (*GroupMemberListWithIsEnd, error) { +func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) (*GetGroupMemberListV2Response, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupAndMemberVersionTableName(), + g.groupMemberTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -349,15 +412,16 @@ func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil }, ) - var groupMemberList *GroupMemberListWithIsEnd - groupMembers, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + groupMembersList, isEnd, err := dataFetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) if err != nil { return nil, err } - groupMemberList.GroupMemberList = groupMembers - groupMemberList.IsEnd = isEnd + resp := &GetGroupMemberListV2Response{ + GroupMembersList: groupMembersList, + IsEnd: isEnd, + } - return groupMemberList, nil + return resp, nil } func (g *Group) GetGroupApplicationListAsRecipient(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) { diff --git a/internal/group/sync2.go b/internal/group/sync2.go index a64a26c8b..38c0eedec 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -42,6 +42,10 @@ func (g *Group) groupTableName() string { return model_struct.LocalGroup{}.TableName() } +func (g *Group) groupMemberTableName() string { + return model_struct.LocalGroupMember{}.TableName() +} + func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { groups, err := g.db.GetJoinedGroupListDB(ctx) if err != nil { diff --git a/internal/group/types.go b/internal/group/types.go index 4275922ae..2d7641a70 100644 --- a/internal/group/types.go +++ b/internal/group/types.go @@ -2,12 +2,12 @@ package group import "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" -type GroupMemberListWithIsEnd struct { - GroupMemberList []*model_struct.LocalGroupMember - IsEnd bool `json:"isEnd"` +type GetGroupMemberListV2Response struct { + GroupMembersList []*model_struct.LocalGroupMember + IsEnd bool `json:"isEnd"` } -type GroupListWithIsEnd struct { - GroupList []*model_struct.LocalGroup - IsEnd bool `json:"isEnd"` +type GetGroupListV2Response struct { + GroupsList []*model_struct.LocalGroup + IsEnd bool `json:"isEnd"` } From f1612e8e05ad26e29974f3d0bd0102ebc37ee2e4 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Mon, 24 Jun 2024 18:43:41 +0800 Subject: [PATCH 50/69] fix uncorrect implements. --- internal/group/sdk.go | 10 +++++----- internal/group/sync2.go | 4 ---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 6ae639eee..c4e9d351a 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -279,7 +279,7 @@ func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -309,7 +309,7 @@ func (g *Group) GetGroupMemberListByJoinTimeFilterV2(ctx context.Context, groupI dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -343,7 +343,7 @@ func (g *Group) GetGroupMemberListByJoinTimeFilterV2(ctx context.Context, groupI func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -368,7 +368,7 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID @@ -393,7 +393,7 @@ func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, func (g *Group) GetGroupMemberListV2(ctx context.Context, groupID string, filter, offset, count int32) (*GetGroupMemberListV2Response, error) { dataFetcher := datafetcher.NewDataFetcher( g.db, - g.groupMemberTableName(), + g.groupAndMemberVersionTableName(), groupID, func(localGroupMember *model_struct.LocalGroupMember) string { return localGroupMember.UserID diff --git a/internal/group/sync2.go b/internal/group/sync2.go index 38c0eedec..a64a26c8b 100644 --- a/internal/group/sync2.go +++ b/internal/group/sync2.go @@ -42,10 +42,6 @@ func (g *Group) groupTableName() string { return model_struct.LocalGroup{}.TableName() } -func (g *Group) groupMemberTableName() string { - return model_struct.LocalGroupMember{}.TableName() -} - func (g *Group) IncrSyncJoinGroupMember(ctx context.Context) error { groups, err := g.db.GetJoinedGroupListDB(ctx) if err != nil { From ccf13ee590e6a5c180ad58ff814980a1481504fc Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:49:16 +0800 Subject: [PATCH 51/69] feat: get group list add page function. --- internal/conversation_msg/conversation_notification.go | 4 ++-- internal/friend/sdk.go | 4 ++-- internal/group/sdk.go | 9 +++++++++ internal/interaction/long_conn_mgr.go | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 2c8392683..11cc42d4d 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -82,9 +82,9 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { err := syncFunc(ctx) duration := time.Since(startTime) if err != nil { - log.ZWarn(ctx, fmt.Sprintf("%s sync err", funcName), err, "duration", duration) + log.ZWarn(ctx, fmt.Sprintf("%s sync err", funcName), err, "duration", duration.Seconds()) } else { - log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration) + log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration.Seconds()) } } case constant.MsgSyncFailed: diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index ee7f671dc..c71dd246a 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -191,7 +191,7 @@ func (f *Friend) GetFriendList(ctx context.Context) ([]*server_api_params.FullUs } func (f *Friend) GetFriendListPage(ctx context.Context, offset, count int32) ([]*server_api_params.FullUserInfo, error) { - datafetcher := datafetcher.NewDataFetcher( + dataFetcher := datafetcher.NewDataFetcher( f.db, f.friendListTableName(), f.loginUserID, @@ -213,7 +213,7 @@ func (f *Friend) GetFriendListPage(ctx context.Context, offset, count int32) ([] }, ) - localFriendList, err := datafetcher.FetchWithPagination(ctx, int(offset), int(count)) + localFriendList, err := dataFetcher.FetchWithPagination(ctx, int(offset), int(count)) if err != nil { return nil, err } diff --git a/internal/group/sdk.go b/internal/group/sdk.go index e52851d94..48535a7be 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -16,6 +16,8 @@ package group import ( "context" + "github.com/openimsdk/tools/errs" + "gorm.io/gorm" "time" "github.com/openimsdk/tools/utils/datautil" @@ -271,6 +273,13 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { + _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) + if errs.Unwrap(err) == gorm.ErrRecordNotFound { + err := g.IncrSyncGroupAndMember(ctx, groupID) + if err != nil { + return nil, err + } + } dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupAndMemberVersionTableName(), diff --git a/internal/interaction/long_conn_mgr.go b/internal/interaction/long_conn_mgr.go index 5869a8f2b..b89b608a0 100644 --- a/internal/interaction/long_conn_mgr.go +++ b/internal/interaction/long_conn_mgr.go @@ -496,7 +496,6 @@ func (c *LongConnMgr) reConn(ctx context.Context, num *int) (needRecon bool, err } c.connWrite.Lock() defer c.connWrite.Unlock() - log.ZDebug(ctx, "conn start") c.listener.OnConnecting() c.SetConnectionStatus(Connecting) url := fmt.Sprintf("%s?sendID=%s&token=%s&platformID=%d&operationID=%s&isBackground=%t", @@ -505,6 +504,7 @@ func (c *LongConnMgr) reConn(ctx context.Context, num *int) (needRecon bool, err if c.IsCompression { url += fmt.Sprintf("&compression=%s", "gzip") } + log.ZDebug(ctx, "conn start", "url", url) resp, err := c.conn.Dial(url, nil) if err != nil { c.SetConnectionStatus(Closed) From 4b79670fdd1bc5058d8d3bea9297b5603646cffe Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Mon, 24 Jun 2024 21:28:23 +0800 Subject: [PATCH 52/69] feat: get group list add page function. --- pkg/db/group_member_model.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 4af2ba374..4f980fbc9 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -194,9 +194,6 @@ func (d *DataBase) InsertGroupMember(ctx context.Context, groupMember *model_str func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList []*model_struct.LocalGroupMember) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - if groupMemberList == nil { - return errors.New("nil") - } return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertMessageList failed") } From 11b866a21e4f05af2fb7b96b58502e0dcc4c229a Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 25 Jun 2024 10:47:01 +0800 Subject: [PATCH 53/69] implement new group module interfaces. --- open_im_sdk/group.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/open_im_sdk/group.go b/open_im_sdk/group.go index 691c3dd0e..db82fa71b 100644 --- a/open_im_sdk/group.go +++ b/open_im_sdk/group.go @@ -88,6 +88,10 @@ func GetJoinedGroupListPage(callback open_im_sdk_callback.Base, operationID stri call(callback, operationID, UserForSDK.Group().GetJoinedGroupListPage, offset, count) } +func GetJoinedGroupListPageV2(callback open_im_sdk_callback.Base, operationID string, offset, count int32) { + call(callback, operationID, UserForSDK.Group().GetJoinedGroupListPageV2, offset, count) +} + func GetSpecifiedGroupsInfo(callback open_im_sdk_callback.Base, operationID string, groupIDList string) { call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupsInfo, groupIDList) } @@ -104,6 +108,10 @@ func GetGroupMemberListByJoinTimeFilter(callback open_im_sdk_callback.Base, oper call(callback, operationID, UserForSDK.Group().GetGroupMemberListByJoinTimeFilter, groupID, offset, count, joinTimeBegin, joinTimeEnd, filterUserIDList) } +func GetGroupMemberListByJoinTimeFilterV2(callback open_im_sdk_callback.Base, operationID string, groupID string, offset int32, count int32, joinTimeBegin int64, joinTimeEnd int64, filterUserIDList string) { + call(callback, operationID, UserForSDK.Group().GetGroupMemberListByJoinTimeFilterV2, groupID, offset, count, joinTimeBegin, joinTimeEnd, filterUserIDList) +} + func GetSpecifiedGroupMembersInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, userIDList string) { call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupMembersInfo, groupID, userIDList) } @@ -112,6 +120,10 @@ func GetGroupMemberList(callback open_im_sdk_callback.Base, operationID string, call(callback, operationID, UserForSDK.Group().GetGroupMemberList, groupID, filter, offset, count) } +func GetGroupMemberListV2(callback open_im_sdk_callback.Base, operationID string, groupID string, filter int32, offset int32, count int32) { + call(callback, operationID, UserForSDK.Group().GetGroupMemberListV2, groupID, filter, offset, count) +} + func GetGroupApplicationListAsRecipient(callback open_im_sdk_callback.Base, operationID string) { call(callback, operationID, UserForSDK.Group().GetGroupApplicationListAsRecipient) } From 7558552d1c04d60e8fad9bd43f78ea5675ba1d40 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 25 Jun 2024 10:51:08 +0800 Subject: [PATCH 54/69] implement new datafetch method in friend module. --- internal/friend/sdk.go | 52 ++++++++++++++++++++++++++++++++++++++++ internal/friend/types.go | 8 +++++++ open_im_sdk/friend.go | 4 ++++ 3 files changed, 64 insertions(+) create mode 100644 internal/friend/types.go diff --git a/internal/friend/sdk.go b/internal/friend/sdk.go index ee7f671dc..13bb47027 100644 --- a/internal/friend/sdk.go +++ b/internal/friend/sdk.go @@ -238,6 +238,58 @@ func (f *Friend) GetFriendListPage(ctx context.Context, offset, count int32) ([] return res, nil } +func (f *Friend) GetFriendListPageV2(ctx context.Context, offset, count int32) (*GetFriendInfoListV2, error) { + datafetcher := datafetcher.NewDataFetcher( + f.db, + f.friendListTableName(), + f.loginUserID, + func(localFriend *model_struct.LocalFriend) string { + return localFriend.FriendUserID + }, + func(ctx context.Context, values []*model_struct.LocalFriend) error { + return f.db.BatchInsertFriend(ctx, values) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + return f.db.GetFriendInfoList(ctx, userIDs) + }, + func(ctx context.Context, userIDs []string) ([]*model_struct.LocalFriend, error) { + serverFriend, err := f.GetDesignatedFriends(ctx, userIDs) + if err != nil { + return nil, err + } + return datautil.Batch(ServerFriendToLocalFriend, serverFriend), nil + }, + ) + + localFriendList, isEnd, err := datafetcher.FetchWithPaginationV2(ctx, int(offset), int(count)) + if err != nil { + return nil, err + } + + // don't need extra handle. only full pull. + localBlackList, err := f.db.GetBlackListDB(ctx) + if err != nil { + return nil, err + } + m := make(map[string]*model_struct.LocalBlack) + for i, black := range localBlackList { + m[black.BlockUserID] = localBlackList[i] + } + fullUserInfo := make([]*server_api_params.FullUserInfo, 0, len(localFriendList)) + for _, localFriend := range localFriendList { + fullUserInfo = append(fullUserInfo, &server_api_params.FullUserInfo{ + PublicInfo: nil, + FriendInfo: localFriend, + BlackInfo: m[localFriend.FriendUserID], + }) + } + response := &GetFriendInfoListV2{ + FullUserInfoList: fullUserInfo, + IsEnd: isEnd, + } + return response, nil +} + func (f *Friend) SearchFriends(ctx context.Context, param *sdk.SearchFriendsParam) ([]*sdk.SearchFriendItem, error) { if len(param.KeywordList) == 0 || (!param.IsSearchNickname && !param.IsSearchUserID && !param.IsSearchRemark) { return nil, sdkerrs.ErrArgs.WrapMsg("keyword is null or search field all false") diff --git a/internal/friend/types.go b/internal/friend/types.go new file mode 100644 index 000000000..5429b5657 --- /dev/null +++ b/internal/friend/types.go @@ -0,0 +1,8 @@ +package friend + +import "github.com/openimsdk/openim-sdk-core/v3/pkg/server_api_params" + +type GetFriendInfoListV2 struct { + FullUserInfoList []*server_api_params.FullUserInfo + IsEnd bool `json:"isEnd"` +} diff --git a/open_im_sdk/friend.go b/open_im_sdk/friend.go index 575600ef3..a7f6bdb8c 100644 --- a/open_im_sdk/friend.go +++ b/open_im_sdk/friend.go @@ -28,6 +28,10 @@ func GetFriendListPage(callback open_im_sdk_callback.Base, operationID string, o call(callback, operationID, UserForSDK.Friend().GetFriendListPage, offset, count) } +func GetFriendListPageV2(callback open_im_sdk_callback.Base, operationID string, offset int32, count int32) { + call(callback, operationID, UserForSDK.Friend().GetFriendListPageV2, offset, count) +} + func SearchFriends(callback open_im_sdk_callback.Base, operationID string, searchParam string) { call(callback, operationID, UserForSDK.Friend().SearchFriends, searchParam) } From 24794c944144c6064f56c71d50196ac72cff3a65 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 25 Jun 2024 12:08:07 +0800 Subject: [PATCH 55/69] refactor: update latest errs pkg and remove unnecessary data transfer. --- pkg/db/chat_log_model.go | 47 +++---- pkg/db/chat_log_reaction_extension_model.go | 17 +-- pkg/db/conversation_model.go | 120 +++++++---------- pkg/db/conversation_unread_message_model.go | 5 +- pkg/db/err_chat_log_model.go | 15 +-- pkg/db/notification_model.go | 9 +- pkg/db/sending_messages_model.go | 10 +- pkg/db/seq_data_model.go | 9 +- pkg/db/stranger_model.go | 13 +- pkg/db/super_group_chat_log_model.go | 135 +++++++------------- pkg/db/super_group_model.go | 15 ++- pkg/db/temp_cache_chat_log_model.go | 7 +- pkg/db/upload_model.go | 3 +- pkg/db/user_command.go | 16 +-- pkg/db/user_model.go | 15 ++- pkg/db/work_moments_model.go | 28 ++-- pkg/db/working_group.go | 7 +- 17 files changed, 200 insertions(+), 271 deletions(-) diff --git a/pkg/db/chat_log_model.go b/pkg/db/chat_log_model.go index f216c353f..f5c0fbcdd 100644 --- a/pkg/db/chat_log_model.go +++ b/pkg/db/chat_log_model.go @@ -20,10 +20,12 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" ) @@ -246,7 +248,7 @@ func (d *DataBase) MessageIfExists(ctx context.Context, ClientMsgID string) (boo t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("client_msg_id = ?", ClientMsgID).Count(&count) if t.Error != nil { - return false, utils.Wrap(t.Error, "MessageIfExists get failed") + return false, errs.WrapMsg(t.Error, "MessageIfExists get failed") } if count != 1 { return false, nil @@ -264,7 +266,7 @@ func (d *DataBase) MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, e t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("seq = ?", seq).Count(&count) if t.Error != nil { - return false, utils.Wrap(t.Error, "MessageIfExistsBySeq get failed") + return false, errs.WrapMsg(t.Error, "MessageIfExistsBySeq get failed") } if count != 1 { return false, nil @@ -289,15 +291,15 @@ func (d *DataBase) MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, e func (d *DataBase) GetAllUnDeleteMessageSeqList(ctx context.Context) ([]uint32, error) { var seqList []uint32 - return seqList, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != ?", constant.MsgStatusHasDeleted).Select("seq").Find(&seqList).Error, "") + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != ?", constant.MsgStatusHasDeleted).Select("seq").Find(&seqList).Error, "") } func (d *DataBase) UpdateColumnsMessageList(ctx context.Context, clientMsgIDList []string, args map[string]interface{}) error { c := model_struct.LocalChatLog{} t := d.conn.WithContext(ctx).Model(&c).Where("client_msg_id IN", clientMsgIDList).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } //funcation (d *DataBase) UpdateColumnsMessageController(ctx context.Context, ClientMsgID string, groupID string, sessionType int32, args map[string]interface{}) error { @@ -327,8 +329,7 @@ func (d *DataBase) UpdateColumnsMessageList(ctx context.Context, clientMsgIDList func (d *DataBase) DeleteAllMessage(ctx context.Context) error { m := model_struct.LocalChatLog{Status: constant.MsgStatusHasDeleted, Content: ""} - err := d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Select("status", "content").Updates(m).Error - return utils.Wrap(err, "delete all message error") + return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Select("status", "content").Updates(m).Error, "delete all message error") } func (d *DataBase) UpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error { d.mRWMutex.Lock() @@ -341,9 +342,9 @@ func (d *DataBase) UpdateMessageStatusBySourceID(ctx context.Context, sourceID s } t := d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(condition, sourceID, sourceID, sessionType).Updates(model_struct.LocalChatLog{Status: status}) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) UpdateMessageStatusBySourceIDController(ctx context.Context, sourceID string, status, sessionType int32) error { switch sessionType { @@ -419,14 +420,8 @@ func (d *DataBase) UpdateMessageStatusBySourceIDController(ctx context.Context, func (d *DataBase) GetAllMessageForTest(ctx context.Context) (result []*model_struct.LocalChatLog, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var messageList []model_struct.LocalChatLog - - err = utils.Wrap(d.conn.WithContext(ctx).Find(&messageList).Error, "GetMessageList failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err + var messageList []*model_struct.LocalChatLog + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&messageList).Error, "GetMessageList failed") } //funcation (d *DataBase) GetMessageListController(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) { @@ -487,14 +482,14 @@ func (d *DataBase) GetTestMessage(ctx context.Context, seq uint32) (*model_struc d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var c model_struct.LocalChatLog - return &c, utils.Wrap(d.conn.WithContext(ctx).Where("seq = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Where("seq = ?", seq).Find(&c).Error, "GetTestMessage failed") } func (d *DataBase) UpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( "send_id = ? and session_type = ? and sender_nick_name != ? ", sendID, sType, nickname).Updates( map[string]interface{}{"sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed") } @@ -502,7 +497,7 @@ func (d *DataBase) UpdateMsgSenderNickname(ctx context.Context, sendID, nickname func (d *DataBase) UpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( "send_id = ? and session_type = ? and sender_face_url != ? ", sendID, sType, faceURL).Updates( map[string]interface{}{"sender_face_url": faceURL}).Error, utils.GetSelfFuncName()+" failed") } @@ -527,8 +522,7 @@ func (d *DataBase) GetMsgSeqByClientMsgID(ctx context.Context, clientMsgID strin d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seq uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("client_msg_id=?", clientMsgID).First(&seq).Error, utils.GetSelfFuncName()+" failed") - return seq, err + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("client_msg_id=?", clientMsgID).First(&seq).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) GetMsgSeqByClientMsgIDController(ctx context.Context, m *sdk_struct.MsgStruct) (uint32, error) { @@ -544,22 +538,19 @@ func (d *DataBase) GetMsgSeqListByGroupID(ctx context.Context, groupID string) ( d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) GetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) GetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } diff --git a/pkg/db/chat_log_reaction_extension_model.go b/pkg/db/chat_log_reaction_extension_model.go index 56a40654e..cb679563a 100644 --- a/pkg/db/chat_log_reaction_extension_model.go +++ b/pkg/db/chat_log_reaction_extension_model.go @@ -20,31 +20,32 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetMessageReactionExtension(ctx context.Context, msgID string) (result *model_struct.LocalChatLogReactionExtensions, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var l model_struct.LocalChatLogReactionExtensions - return &l, utils.Wrap(d.conn.WithContext(ctx).Where("client_msg_id = ?", + return &l, errs.WrapMsg(d.conn.WithContext(ctx).Where("client_msg_id = ?", msgID).Take(&l).Error, "GetMessageReactionExtension failed") } func (d *DataBase) InsertMessageReactionExtension(ctx context.Context, messageReactionExtension *model_struct.LocalChatLogReactionExtensions) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(messageReactionExtension).Error, "InsertMessageReactionExtension failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(messageReactionExtension).Error, "InsertMessageReactionExtension failed") } func (d *DataBase) UpdateMessageReactionExtension(ctx context.Context, c *model_struct.LocalChatLogReactionExtensions) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateConversation failed") + return errs.WrapMsg(t.Error, "UpdateConversation failed") } // func (d *DataBase) GetAndUpdateMessageReactionExtension(ctx context.Context, msgID string, m map[string]*sdkws.KeyValue) error { @@ -70,7 +71,7 @@ func (d *DataBase) UpdateMessageReactionExtension(ctx context.Context, c *model_ // temp.LocalReactionExtensions = []byte(utils.StructToJsonString(oldKeyValue)) // t := d.conn.WithContext(ctx).Updates(temp) // if t.RowsAffected == 0 { -// return utils.Wrap(errors.New("RowsAffected == 0"), "no update") +// return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") // } // } // return nil @@ -102,7 +103,7 @@ func (d *DataBase) DeleteMessageReactionExtension(ctx context.Context, msgID str // temp.LocalReactionExtensions = []byte(utils.StructToJsonString(oldKeyValue)) // t := d.conn.WithContext(ctx).Updates(temp) // if t.RowsAffected == 0 { -// return utils.Wrap(errors.New("RowsAffected == 0"), "no update") +// return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") // } // } // return nil @@ -111,7 +112,7 @@ func (d *DataBase) DeleteMessageReactionExtension(ctx context.Context, msgID str // d.mRWMutex.Lock() // defer d.mRWMutex.Unlock() // var messageList []model_struct.LocalChatLogReactionExtensions -// err = utils.Wrap(d.conn.WithContext(ctx).Where("client_msg_id IN ?", msgIDList).Find(&messageList).Error, "GetMultipleMessageReactionExtension failed") +// err = errs.WrapMsg(d.conn.WithContext(ctx).Where("client_msg_id IN ?", msgIDList).Find(&messageList).Error, "GetMultipleMessageReactionExtension failed") // for _, v := range messageList { // v1 := v // result = append(result, &v1) diff --git a/pkg/db/conversation_model.go b/pkg/db/conversation_model.go index 1fcba2dc5..f4324dabc 100644 --- a/pkg/db/conversation_model.go +++ b/pkg/db/conversation_model.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" @@ -32,7 +33,7 @@ import ( func (d *DataBase) GetConversationByUserID(ctx context.Context, userID string) (*model_struct.LocalConversation, error) { var conversation model_struct.LocalConversation - err := utils.Wrap(d.conn.WithContext(ctx).Where("user_id=?", userID).Find(&conversation).Error, "GetConversationByUserID error") + err := errs.WrapMsg(d.conn.WithContext(ctx).Where("user_id=?", userID).Find(&conversation).Error, "GetConversationByUserID error") return &conversation, err } @@ -40,7 +41,7 @@ func (d *DataBase) GetAllConversationListDB(ctx context.Context) ([]*model_struc d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var conversationList []*model_struct.LocalConversation - err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Find(&conversationList).Error, + err := errs.WrapMsg(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Find(&conversationList).Error, "GetAllConversationList failed") if err != nil { return nil, err @@ -48,56 +49,41 @@ func (d *DataBase) GetAllConversationListDB(ctx context.Context) ([]*model_struc return conversationList, err } func (d *DataBase) FindAllConversationConversationID(ctx context.Context) (conversationIDs []string, err error) { - return conversationIDs, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("latest_msg_send_time > ?", 0).Pluck("conversation_id", &conversationIDs).Error, "") + return conversationIDs, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("latest_msg_send_time > ?", 0).Pluck("conversation_id", &conversationIDs).Error, "") } func (d *DataBase) GetHiddenConversationList(ctx context.Context) ([]*model_struct.LocalConversation, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var conversationList []model_struct.LocalConversation - err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time = ?", 0).Find(&conversationList).Error, + var conversationList []*model_struct.LocalConversation + return conversationList, errs.WrapMsg(d.conn.WithContext(ctx).Where("latest_msg_send_time = ?", 0).Find(&conversationList).Error, "GetHiddenConversationList failed") - var transfer []*model_struct.LocalConversation - for _, v := range conversationList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err } func (d *DataBase) GetAllConversations(ctx context.Context) ([]*model_struct.LocalConversation, error) { var conversationList []*model_struct.LocalConversation - err := utils.Wrap(d.conn.WithContext(ctx).Find(&conversationList).Error, "GetAllConversations failed") - return conversationList, err + return conversationList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&conversationList).Error, "GetAllConversations failed") } func (d *DataBase) GetAllConversationIDList(ctx context.Context) (result []string, err error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() var c model_struct.LocalConversation - err = d.conn.WithContext(ctx).Model(&c).Pluck("conversation_id", &result).Error - return result, utils.Wrap(err, "GetAllConversationIDList failed ") + return result, errs.WrapMsg(d.conn.WithContext(ctx).Model(&c).Pluck("conversation_id", &result).Error, "GetAllConversationIDList failed ") } func (d *DataBase) GetAllSingleConversationIDList(ctx context.Context) (result []string, err error) { d.groupMtx.Lock() defer d.groupMtx.Unlock() var c model_struct.LocalConversation - err = d.conn.WithContext(ctx).Model(&c).Where("conversation_type = ?", constant.SingleChatType).Pluck("conversation_id", &result).Error - return result, utils.Wrap(err, "GetAllConversationIDList failed ") + return result, errs.WrapMsg(d.conn.WithContext(ctx).Model(&c).Where("conversation_type = ?", constant.SingleChatType).Pluck("conversation_id", &result).Error, "GetAllConversationIDList failed ") } func (d *DataBase) GetConversationListSplitDB(ctx context.Context, offset, count int) ([]*model_struct.LocalConversation, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var conversationList []model_struct.LocalConversation - err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Offset(offset).Limit(count).Find(&conversationList).Error, + var conversationList []*model_struct.LocalConversation + return conversationList, errs.WrapMsg(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Offset(offset).Limit(count).Find(&conversationList).Error, "GetFriendList failed") - var transfer []*model_struct.LocalConversation - for _, v := range conversationList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err } func (d *DataBase) BatchInsertConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error { if conversationList == nil { @@ -106,7 +92,7 @@ func (d *DataBase) BatchInsertConversationList(ctx context.Context, conversation d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(conversationList).Error, "BatchInsertConversationList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(conversationList).Error, "BatchInsertConversationList failed") } func (d *DataBase) UpdateOrCreateConversations(ctx context.Context, conversationList []*model_struct.LocalConversation) error { @@ -140,18 +126,18 @@ func (d *DataBase) UpdateOrCreateConversations(ctx context.Context, conversation func (d *DataBase) InsertConversation(ctx context.Context, conversationList *model_struct.LocalConversation) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(conversationList).Error, "InsertConversation failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(conversationList).Error, "InsertConversation failed") } func (d *DataBase) DeleteConversation(ctx context.Context, conversationID string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id = ?", conversationID).Delete(&model_struct.LocalConversation{}).Error, "DeleteConversation failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Where("conversation_id = ?", conversationID).Delete(&model_struct.LocalConversation{}).Error, "DeleteConversation failed") } func (d *DataBase) GetConversation(ctx context.Context, conversationID string) (*model_struct.LocalConversation, error) { var c model_struct.LocalConversation - return &c, utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Where("conversation_id = ?", conversationID).Take(&c).Error, "GetConversation failed, conversationID: "+conversationID) } @@ -161,9 +147,9 @@ func (d *DataBase) UpdateConversation(ctx context.Context, c *model_struct.Local d.conn.WithContext(ctx).Logger.LogMode(6) t := d.conn.WithContext(ctx).Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateConversation failed") + return errs.WrapMsg(t.Error, "UpdateConversation failed") } func (d *DataBase) UpdateConversationForSync(ctx context.Context, c *model_struct.LocalConversation) error { @@ -174,16 +160,16 @@ func (d *DataBase) UpdateConversationForSync(ctx context.Context, c *model_struc "group_at_type": c.GroupAtType, "is_not_in_group": c.IsNotInGroup, "update_unread_count_time": c.UpdateUnreadCountTime, "ex": c.Ex, "attached_info": c.AttachedInfo, "burn_duration": c.BurnDuration, "msg_destruct_time": c.MsgDestructTime, "is_msg_destruct": c.IsMsgDestruct}) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateConversation failed") + return errs.WrapMsg(t.Error, "UpdateConversation failed") } func (d *DataBase) BatchUpdateConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error { for _, v := range conversationList { err := d.UpdateConversation(ctx, v) if err != nil { - return utils.Wrap(err, "BatchUpdateConversationList failed") + return errs.WrapMsg(err, "BatchUpdateConversationList failed") } } @@ -196,7 +182,7 @@ func (d *DataBase) ConversationIfExists(ctx context.Context, conversationID stri t := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id = ?", conversationID).Count(&count) if t.Error != nil { - return false, utils.Wrap(t.Error, "ConversationIfExists get failed") + return false, errs.WrapMsg(t.Error, "ConversationIfExists get failed") } if count != 1 { return false, nil @@ -213,9 +199,9 @@ func (d *DataBase) ResetConversation(ctx context.Context, conversationID string) c := model_struct.LocalConversation{ConversationID: conversationID, UnreadCount: 0, LatestMsg: "", LatestMsgSendTime: 0, DraftText: "", DraftTextTime: 0} t := d.conn.WithContext(ctx).Select("unread_count", "latest_msg", "latest_msg_send_time", "draft_text", "draft_text_time").Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "ResetConversation failed") + return errs.WrapMsg(t.Error, "ResetConversation failed") } // ResetAllConversation Reset ALL conversation is equivalent to deleting the conversation, @@ -226,9 +212,9 @@ func (d *DataBase) ResetAllConversation(ctx context.Context) error { c := model_struct.LocalConversation{UnreadCount: 0, LatestMsg: "", LatestMsgSendTime: 0, DraftText: "", DraftTextTime: 0} t := d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Select("unread_count", "latest_msg", "latest_msg_send_time", "draft_text", "draft_text_time").Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "ResetConversation failed") + return errs.WrapMsg(t.Error, "ResetConversation failed") } // Clear the conversation, which is used to delete the conversation history message and clear the conversation at the same time. @@ -240,9 +226,9 @@ func (d *DataBase) ClearConversation(ctx context.Context, conversationID string) c := model_struct.LocalConversation{ConversationID: conversationID, UnreadCount: 0, LatestMsg: "", DraftText: "", DraftTextTime: 0} t := d.conn.WithContext(ctx).Select("unread_count", "latest_msg", "draft_text", "draft_text_time").Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "ClearConversation failed") + return errs.WrapMsg(t.Error, "ClearConversation failed") } func (d *DataBase) SetConversationDraftDB(ctx context.Context, conversationID, draftText string) error { @@ -252,9 +238,9 @@ func (d *DataBase) SetConversationDraftDB(ctx context.Context, conversationID, d t := d.conn.WithContext(ctx).Exec("update local_conversations set draft_text=?,draft_text_time=?,latest_msg_send_time=case when latest_msg_send_time=? then ? else latest_msg_send_time end where conversation_id=?", draftText, nowTime, 0, nowTime, conversationID) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "SetConversationDraft failed") + return errs.WrapMsg(t.Error, "SetConversationDraft failed") } func (d *DataBase) RemoveConversationDraft(ctx context.Context, conversationID, draftText string) error { d.mRWMutex.Lock() @@ -262,9 +248,9 @@ func (d *DataBase) RemoveConversationDraft(ctx context.Context, conversationID, c := model_struct.LocalConversation{ConversationID: conversationID, DraftText: draftText, DraftTextTime: 0} t := d.conn.WithContext(ctx).Select("draft_text", "draft_text_time").Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "RemoveConversationDraft failed") + return errs.WrapMsg(t.Error, "RemoveConversationDraft failed") } func (d *DataBase) UnPinConversation(ctx context.Context, conversationID string, isPinned int) error { d.mRWMutex.Lock() @@ -272,9 +258,9 @@ func (d *DataBase) UnPinConversation(ctx context.Context, conversationID string, t := d.conn.WithContext(ctx).Exec("update local_conversations set is_pinned=?,draft_text_time=case when draft_text=? then ? else draft_text_time end where conversation_id=?", isPinned, "", 0, conversationID) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UnPinConversation failed") + return errs.WrapMsg(t.Error, "UnPinConversation failed") } func (d *DataBase) UpdateColumnsConversation(ctx context.Context, conversationID string, args map[string]interface{}) error { @@ -282,21 +268,21 @@ func (d *DataBase) UpdateColumnsConversation(ctx context.Context, conversationID defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Model(model_struct.LocalConversation{ConversationID: conversationID}).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errs.ErrRecordNotFound, "no update") + return errs.WrapMsg(errs.ErrRecordNotFound, "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } func (d *DataBase) UpdateAllConversation(ctx context.Context, conversation *model_struct.LocalConversation) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() if conversation.ConversationID != "" { - return utils.Wrap(errors.New("not update all conversation"), "UpdateAllConversation failed") + return errs.WrapMsg(errors.New("not update all conversation"), "UpdateAllConversation failed") } t := d.conn.WithContext(ctx).Model(conversation).Updates(conversation) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } func (d *DataBase) IncrConversationUnreadCount(ctx context.Context, conversationID string) error { d.mRWMutex.Lock() @@ -304,9 +290,9 @@ func (d *DataBase) IncrConversationUnreadCount(ctx context.Context, conversation c := model_struct.LocalConversation{ConversationID: conversationID} t := d.conn.WithContext(ctx).Model(&c).Update("unread_count", gorm.Expr("unread_count+?", 1)) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "IncrConversationUnreadCount failed") + return errs.WrapMsg(t.Error, "IncrConversationUnreadCount failed") } func (d *DataBase) GetTotalUnreadMsgCountDB(ctx context.Context) (totalUnreadCount int32, err error) { d.mRWMutex.Lock() @@ -314,7 +300,7 @@ func (d *DataBase) GetTotalUnreadMsgCountDB(ctx context.Context) (totalUnreadCou var result []int64 err = d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("recv_msg_opt < ? and latest_msg_send_time > ?", constant.ReceiveNotNotifyMessage, 0).Pluck("unread_count", &result).Error if err != nil { - return totalUnreadCount, utils.Wrap(errors.New("GetTotalUnreadMsgCount err"), "GetTotalUnreadMsgCount err") + return totalUnreadCount, errs.WrapMsg(errors.New("GetTotalUnreadMsgCount err"), "GetTotalUnreadMsgCount err") } for _, v := range result { totalUnreadCount += int32(v) @@ -327,16 +313,16 @@ func (d *DataBase) SetMultipleConversationRecvMsgOpt(ctx context.Context, conver defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id IN ?", conversationIDList).Updates(map[string]interface{}{"recv_msg_opt": opt}) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "SetMultipleConversationRecvMsgOpt failed") + return errs.WrapMsg(t.Error, "SetMultipleConversationRecvMsgOpt failed") } func (d *DataBase) GetMultipleConversationDB(ctx context.Context, conversationIDList []string) (result []*model_struct.LocalConversation, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var conversationList []model_struct.LocalConversation - err = utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id IN ?", conversationIDList).Find(&conversationList).Error, "GetMultipleConversation failed") + err = errs.WrapMsg(d.conn.WithContext(ctx).Where("conversation_id IN ?", conversationIDList).Find(&conversationList).Error, "GetMultipleConversation failed") for _, v := range conversationList { v1 := v result = append(result, &v1) @@ -350,18 +336,18 @@ func (d *DataBase) DecrConversationUnreadCount(ctx context.Context, conversation c := model_struct.LocalConversation{ConversationID: conversationID} t := tx.Model(&c).Update("unread_count", gorm.Expr("unread_count-?", count)) if t.Error != nil { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } if err := tx.Where("conversation_id = ?", conversationID).Take(&c).Error; err != nil { tx.Rollback() - return utils.Wrap(errors.New("get conversation err"), "") + return errs.WrapMsg(errors.New("get conversation err"), "") } if c.UnreadCount < 0 { log.ZWarn(ctx, "decr unread count < 0", nil, "conversationID", conversationID, "count", count) if t = tx.Model(&c).Update("unread_count", 0); t.Error != nil { tx.Rollback() - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } } tx.Commit() @@ -370,14 +356,6 @@ func (d *DataBase) DecrConversationUnreadCount(ctx context.Context, conversation func (d *DataBase) SearchConversations(ctx context.Context, searchParam string) ([]*model_struct.LocalConversation, error) { // Define the search condition based on the searchParam condition := fmt.Sprintf("show_name like %q ", "%"+searchParam+"%") - - var conversationList []model_struct.LocalConversation - err := d.conn.WithContext(ctx).Where(condition).Order("latest_msg_send_time DESC").Find(&conversationList).Error - var transfer []*model_struct.LocalConversation - for _, v := range conversationList { - v1 := v // Create a copy to avoid referencing the loop variable - transfer = append(transfer, &v1) - } - - return transfer, utils.Wrap(err, "SearchConversation failed ") + var conversationList []*model_struct.LocalConversation + return conversationList, errs.WrapMsg(d.conn.WithContext(ctx).Where(condition).Order("latest_msg_send_time DESC").Find(&conversationList).Error, "SearchConversation failed ") } diff --git a/pkg/db/conversation_unread_message_model.go b/pkg/db/conversation_unread_message_model.go index 33242ccbe..e309fdde7 100644 --- a/pkg/db/conversation_unread_message_model.go +++ b/pkg/db/conversation_unread_message_model.go @@ -19,8 +19,9 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) BatchInsertConversationUnreadMessageList(ctx context.Context, messageList []*model_struct.LocalConversationUnreadMessage) error { @@ -29,7 +30,7 @@ func (d *DataBase) BatchInsertConversationUnreadMessageList(ctx context.Context, } d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertConversationUnreadMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertConversationUnreadMessageList failed") } func (d *DataBase) DeleteConversationUnreadMessageList(ctx context.Context, conversationID string, sendTime int64) int64 { d.mRWMutex.Lock() diff --git a/pkg/db/err_chat_log_model.go b/pkg/db/err_chat_log_model.go index 47d39c876..9c2a88097 100644 --- a/pkg/db/err_chat_log_model.go +++ b/pkg/db/err_chat_log_model.go @@ -19,9 +19,11 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) initSuperLocalErrChatLog(ctx context.Context, groupID string) { @@ -34,19 +36,17 @@ func (d *DataBase) SuperBatchInsertExceptionMsg(ctx context.Context, MessageList return nil } d.initSuperLocalErrChatLog(ctx, groupID) - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "BatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "BatchInsertMessageList failed") } func (d *DataBase) GetAbnormalMsgSeq(ctx context.Context) (int64, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seq int64 - err := d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error - return seq, utils.Wrap(err, "GetAbnormalMsgSeq") + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error, "GetAbnormalMsgSeq") } func (d *DataBase) GetAbnormalMsgSeqList(ctx context.Context) ([]int64, error) { var seqList []int64 - err := d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("seq").Find(&seqList).Error - return seqList, utils.Wrap(err, "GetAbnormalMsgSeqList") + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("seq").Find(&seqList).Error, "GetAbnormalMsgSeqList") } func (d *DataBase) BatchInsertExceptionMsg(ctx context.Context, messageList []*model_struct.LocalErrChatLog) error { if messageList == nil { @@ -54,7 +54,7 @@ func (d *DataBase) BatchInsertExceptionMsg(ctx context.Context, messageList []*m } d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertMessageList failed") } func (d *DataBase) BatchInsertExceptionMsgController(ctx context.Context, messageList []*model_struct.LocalErrChatLog) error { if len(messageList) == 0 { @@ -72,6 +72,5 @@ func (d *DataBase) GetConversationAbnormalMsgSeq(ctx context.Context, conversati if !d.conn.WithContext(ctx).Migrator().HasTable(utils.GetErrTableName(conversationID)) { return 0, nil } - err := d.conn.WithContext(ctx).Table(utils.GetErrTableName(conversationID)).Select("IFNULL(max(seq),0)").Find(&seq).Error - return seq, utils.Wrap(err, "GetConversationNormalMsgSeq") + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetErrTableName(conversationID)).Select("IFNULL(max(seq),0)").Find(&seq).Error, "GetConversationNormalMsgSeq") } diff --git a/pkg/db/notification_model.go b/pkg/db/notification_model.go index 70fc13853..f62f59141 100644 --- a/pkg/db/notification_model.go +++ b/pkg/db/notification_model.go @@ -19,8 +19,9 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error { @@ -28,10 +29,10 @@ func (d *DataBase) SetNotificationSeq(ctx context.Context, conversationID string defer d.mRWMutex.Unlock() cursor := d.conn.WithContext(ctx).Model(&model_struct.NotificationSeqs{}).Where("conversation_id = ?", conversationID).Updates(map[string]interface{}{"seq": seq}) if cursor.Error != nil { - return utils.Wrap(cursor.Error, "Updates failed") + return errs.WrapMsg(cursor.Error, "Updates failed") } if cursor.RowsAffected == 0 { - return utils.Wrap(d.conn.WithContext(ctx).Create(&model_struct.NotificationSeqs{ConversationID: conversationID, Seq: seq}).Error, "Create failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(&model_struct.NotificationSeqs{ConversationID: conversationID, Seq: seq}).Error, "Create failed") } return nil } @@ -40,5 +41,5 @@ func (d *DataBase) GetNotificationAllSeqs(ctx context.Context) ([]*model_struct. d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqs []*model_struct.NotificationSeqs - return seqs, utils.Wrap(d.conn.WithContext(ctx).Where("1=1").Find(&seqs).Error, "GetNotificationAllSeqs failed") + return seqs, errs.WrapMsg(d.conn.WithContext(ctx).Where("1=1").Find(&seqs).Error, "GetNotificationAllSeqs failed") } diff --git a/pkg/db/sending_messages_model.go b/pkg/db/sending_messages_model.go index 5065622fb..6947faded 100644 --- a/pkg/db/sending_messages_model.go +++ b/pkg/db/sending_messages_model.go @@ -19,25 +19,25 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertSendingMessage(ctx context.Context, message *model_struct.LocalSendingMessages) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(message).Error, "InsertSendingMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(message).Error, "InsertSendingMessage failed") } func (d *DataBase) DeleteSendingMessage(ctx context.Context, conversationID, clientMsgID string) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() localSendingMessage := model_struct.LocalSendingMessages{ConversationID: conversationID, ClientMsgID: clientMsgID} - return utils.Wrap(d.conn.WithContext(ctx).Delete(&localSendingMessage).Error, "DeleteSendingMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Delete(&localSendingMessage).Error, "DeleteSendingMessage failed") } func (d *DataBase) GetAllSendingMessages(ctx context.Context) (friendRequests []*model_struct.LocalSendingMessages, err error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - err = utils.Wrap(d.conn.WithContext(ctx).Find(&friendRequests).Error, "GetAllSendingMessages failed") - return friendRequests, utils.Wrap(err, "GetAllSendingMessages failed") + return friendRequests, errs.WrapMsg(d.conn.WithContext(ctx).Find(&friendRequests).Error, "GetAllSendingMessages failed") } diff --git a/pkg/db/seq_data_model.go b/pkg/db/seq_data_model.go index 2e3561184..5c98468e4 100644 --- a/pkg/db/seq_data_model.go +++ b/pkg/db/seq_data_model.go @@ -19,22 +19,23 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetMinSeq(ctx context.Context, ID string) (uint32, error) { var seqData model_struct.LocalSeq - return seqData.MinSeq, utils.Wrap(d.conn.WithContext(ctx).First(&seqData).Error, "GetMinSeq failed") + return seqData.MinSeq, errs.WrapMsg(d.conn.WithContext(ctx).First(&seqData).Error, "GetMinSeq failed") } func (d *DataBase) SetMinSeq(ctx context.Context, ID string, minSeq uint32) error { seqData := model_struct.LocalSeq{ID: ID, MinSeq: minSeq} t := d.conn.WithContext(ctx).Updates(&seqData) if t.RowsAffected == 0 { - return utils.Wrap(d.conn.WithContext(ctx).Create(seqData).Error, "Updates failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(seqData).Error, "Updates failed") } else { - return utils.Wrap(t.Error, "SetMinSeq failed") + return errs.WrapMsg(t.Error, "SetMinSeq failed") } } diff --git a/pkg/db/stranger_model.go b/pkg/db/stranger_model.go index b56b66707..af7242844 100644 --- a/pkg/db/stranger_model.go +++ b/pkg/db/stranger_model.go @@ -20,22 +20,17 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" ) func (d *DataBase) GetStrangerInfo(ctx context.Context, userIDs []string) ([]*model_struct.LocalStranger, error) { d.friendMtx.Lock() defer d.friendMtx.Unlock() - var friendList []model_struct.LocalStranger - err := utils.Wrap(d.conn.WithContext(ctx).Where("user_id IN ?", userIDs).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed") - var transfer []*model_struct.LocalStranger - for _, v := range friendList { - v1 := v - transfer = append(transfer, &v1) - } - return transfer, err + var friendList []*model_struct.LocalStranger + return friendList, errs.WrapMsg(d.conn.WithContext(ctx).Where("user_id IN ?", userIDs).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed") } func (d *DataBase) SetStrangerInfo(ctx context.Context, localStrangerList []*model_struct.LocalStranger) error { diff --git a/pkg/db/super_group_chat_log_model.go b/pkg/db/super_group_chat_log_model.go index ac80e294e..b7c81f672 100644 --- a/pkg/db/super_group_chat_log_model.go +++ b/pkg/db/super_group_chat_log_model.go @@ -21,10 +21,12 @@ import ( "context" "errors" "fmt" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" "github.com/openimsdk/openim-sdk-core/v3/sdk_struct" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" ) @@ -40,20 +42,20 @@ func (d *DataBase) SuperGroupBatchInsertMessageList(ctx context.Context, Message } d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "SuperGroupBatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "SuperGroupBatchInsertMessageList failed") } func (d *DataBase) SuperGroupInsertMessage(ctx context.Context, Message *model_struct.LocalChatLog, groupID string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(Message).Error, "SuperGroupInsertMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(Message).Error, "SuperGroupInsertMessage failed") } func (d *DataBase) SuperGroupDeleteAllMessage(ctx context.Context, groupID string) error { - return utils.Wrap(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Table(utils.GetConversationTableName(groupID)).Delete(&model_struct.LocalChatLog{}).Error, "SuperGroupDeleteAllMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Table(utils.GetConversationTableName(groupID)).Delete(&model_struct.LocalChatLog{}).Error, "SuperGroupDeleteAllMessage failed") } func (d *DataBase) SuperGroupSearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var messageList []model_struct.LocalChatLog + var messageList []*model_struct.LocalChatLog var condition string var subCondition string if keywordListMatchType == constant.KeywordMatchOr { @@ -81,15 +83,8 @@ func (d *DataBase) SuperGroupSearchMessageByKeyword(ctx context.Context, content } } condition = fmt.Sprintf("recv_id=%q And send_time between %d and %d AND status <=%d And content_type IN ? ", sourceID, startTime, endTime, constant.MsgStatusSendFailed) - condition += subCondition - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "InsertMessage failed") - - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "InsertMessage failed") } func (d *DataBase) SuperGroupSearchAllMessageByContentType(ctx context.Context, groupID string, contentType int32) (result []*model_struct.LocalChatLog, err error) { @@ -98,20 +93,13 @@ func (d *DataBase) SuperGroupSearchAllMessageByContentType(ctx context.Context, } func (d *DataBase) SuperGroupSearchMessageByContentType(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) { - var messageList []model_struct.LocalChatLog - var condition string - condition = fmt.Sprintf("session_type=%d And recv_id==%q And send_time between %d and %d AND status <=%d And content_type IN ?", sessionType, sourceID, startTime, endTime, constant.MsgStatusSendFailed) - - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "SearchMessage failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err + var messageList []*model_struct.LocalChatLog + condition := fmt.Sprintf("session_type=%d And recv_id==%q And send_time between %d and %d AND status <=%d And content_type IN ?", sessionType, sourceID, startTime, endTime, constant.MsgStatusSendFailed) + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "SearchMessage failed") } func (d *DataBase) SuperGroupSearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64, groupID string) (result []*model_struct.LocalChatLog, err error) { - var messageList []model_struct.LocalChatLog + var messageList []*model_struct.LocalChatLog var condition string var subCondition string if keywordListMatchType == constant.KeywordMatchOr { @@ -140,12 +128,7 @@ func (d *DataBase) SuperGroupSearchMessageByContentTypeAndKeyword(ctx context.Co } condition = fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed) condition += subCondition - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(condition, contentType).Order("send_time DESC").Find(&messageList).Error, "SearchMessage failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(condition, contentType).Order("send_time DESC").Find(&messageList).Error, "SearchMessage failed") } func (d *DataBase) SuperGroupBatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error { if MessageList == nil { @@ -159,7 +142,7 @@ func (d *DataBase) SuperGroupBatchUpdateMessageList(ctx context.Context, Message v1.Status = v.Status err := d.SuperGroupUpdateMessage(ctx, v1) if err != nil { - return utils.Wrap(err, "BatchUpdateMessageList failed") + return errs.WrapMsg(err, "BatchUpdateMessageList failed") } } @@ -173,7 +156,7 @@ func (d *DataBase) SuperGroupMessageIfExists(ctx context.Context, ClientMsgID st t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("client_msg_id = ?", ClientMsgID).Count(&count) if t.Error != nil { - return false, utils.Wrap(t.Error, "MessageIfExists get failed") + return false, errs.WrapMsg(t.Error, "MessageIfExists get failed") } if count != 1 { return false, nil @@ -191,7 +174,7 @@ func (d *DataBase) SuperGroupMessageIfExistsBySeq(ctx context.Context, seq int64 t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("seq = ?", seq).Count(&count) if t.Error != nil { - return false, utils.Wrap(t.Error, "MessageIfExistsBySeq get failed") + return false, errs.WrapMsg(t.Error, "MessageIfExistsBySeq get failed") } if count != 1 { return false, nil @@ -204,13 +187,13 @@ func (d *DataBase) SuperGroupGetMessage(ctx context.Context, msg *sdk_struct.Msg d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var c model_struct.LocalChatLog - return &c, utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(msg.GroupID)).Where("client_msg_id = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(msg.GroupID)).Where("client_msg_id = ?", msg.ClientMsgID).Take(&c).Error, "GetMessage failed") } func (d *DataBase) SuperGroupGetAllUnDeleteMessageSeqList(ctx context.Context) ([]uint32, error) { var seqList []uint32 - return seqList, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != 4").Select("seq").Find(&seqList).Error, "") + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != 4").Select("seq").Find(&seqList).Error, "") } func (d *DataBase) SuperGroupUpdateColumnsMessage(ctx context.Context, ClientMsgID, groupID string, args map[string]interface{}) error { @@ -219,34 +202,34 @@ func (d *DataBase) SuperGroupUpdateColumnsMessage(ctx context.Context, ClientMsg t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where( "client_msg_id = ? ", ClientMsgID).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } func (d *DataBase) SuperGroupUpdateMessage(ctx context.Context, c *model_struct.LocalChatLog) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(c.RecvID)).Updates(c) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessage failed") + return errs.WrapMsg(t.Error, "UpdateMessage failed") } func (d *DataBase) SuperGroupUpdateSpecificContentTypeMessage(ctx context.Context, contentType int, groupID string, args map[string]interface{}) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("content_type = ?", contentType).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessage failed") + return errs.WrapMsg(t.Error, "UpdateMessage failed") } //funcation (d *DataBase) SuperGroupDeleteAllMessage(ctx context.Context, ) error { // d.mRWMutex.Lock() // defer d.mRWMutex.Unlock() // err := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Exec("update local_chat_logs set status = ?,content = ? ", constant.MsgStatusHasDeleted, "").Error -// return utils.Wrap(err, "delete all message error") +// return errs.WrapMsg(err, "delete all message error") //} func (d *DataBase) SuperGroupUpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error { @@ -260,24 +243,24 @@ func (d *DataBase) SuperGroupUpdateMessageStatusBySourceID(ctx context.Context, } t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, sourceID, sessionType).Updates(model_struct.LocalChatLog{Status: status}) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) SuperGroupUpdateMessageTimeAndStatus(ctx context.Context, msg *sdk_struct.MsgStruct) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(msg.GroupID)).Where("client_msg_id=? And seq=?", msg.ClientMsgID, 0).Updates(model_struct.LocalChatLog{Status: msg.Status, SendTime: msg.SendTime, ServerMsgID: msg.ServerMsgID}) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "SuperGroupUpdateMessageTimeAndStatus failed") + return errs.WrapMsg(t.Error, "SuperGroupUpdateMessageTimeAndStatus failed") } func (d *DataBase) SuperGroupGetMessageList(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var messageList []model_struct.LocalChatLog + var messageList []*model_struct.LocalChatLog var condition, timeOrder, timeSymbol string if isReverse { timeOrder = "send_time ASC" @@ -288,17 +271,12 @@ func (d *DataBase) SuperGroupGetMessageList(ctx context.Context, sourceID string } condition = " recv_id = ? AND status <=? And session_type = ? And send_time " + timeSymbol + " ?" - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType, startTime). + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType, startTime). Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err } func (d *DataBase) SuperGroupGetMessageListNoTime(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) { d.initSuperLocalChatLog(ctx, sourceID) - var messageList []model_struct.LocalChatLog + var messageList []*model_struct.LocalChatLog var condition, timeOrder string if isReverse { timeOrder = "send_time ASC" @@ -306,26 +284,15 @@ func (d *DataBase) SuperGroupGetMessageListNoTime(ctx context.Context, sourceID timeOrder = "send_time DESC" } condition = "recv_id = ? AND status <=? And session_type = ? " - - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType). + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType). Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err } func (d *DataBase) SuperGroupGetSendingMessageList(ctx context.Context, groupID string) (result []*model_struct.LocalChatLog, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - var messageList []model_struct.LocalChatLog - err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("status = ?", constant.MsgStatusSending).Find(&messageList).Error, "GetMessageList failed") - for _, v := range messageList { - v1 := v - result = append(result, &v1) - } - return result, err + var messageList []*model_struct.LocalChatLog + return messageList, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("status = ?", constant.MsgStatusSending).Find(&messageList).Error, "GetMessageList failed") } func (d *DataBase) SuperGroupUpdateGroupMessageHasRead(ctx context.Context, msgIDList []string, groupID string) error { @@ -333,44 +300,42 @@ func (d *DataBase) SuperGroupUpdateGroupMessageHasRead(ctx context.Context, msgI defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(" client_msg_id in ?", msgIDList).Update("is_read", constant.HasRead) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) SuperGroupUpdateGroupMessageFields(ctx context.Context, msgIDList []string, groupID string, args map[string]interface{}) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(" client_msg_id in ?", msgIDList).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed") + return errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed") } func (d *DataBase) SuperGroupGetNormalMsgSeq(ctx context.Context) (int64, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seq int64 - err := d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error - return seq, utils.Wrap(err, "GetNormalMsgSeq") + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error, "GetNormalMsgSeq") } func (d *DataBase) SuperGroupGetNormalMinSeq(ctx context.Context, groupID string) (int64, error) { var seq int64 - err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("IFNULL(min(seq),0)").Where("seq >?", 0).Find(&seq).Error - return seq, utils.Wrap(err, "SuperGroupGetNormalMinSeq") + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("IFNULL(min(seq),0)").Where("seq >?", 0).Find(&seq).Error, "SuperGroupGetNormalMinSeq") } func (d *DataBase) SuperGroupGetTestMessage(ctx context.Context, seq int64) (*model_struct.LocalChatLog, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var c model_struct.LocalChatLog - return &c, utils.Wrap(d.conn.WithContext(ctx).Where("seq = ?", + return &c, errs.WrapMsg(d.conn.WithContext(ctx).Where("seq = ?", seq).Find(&c).Error, "GetTestMessage failed") } func (d *DataBase) SuperGroupUpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( "send_id = ? and session_type = ? and sender_nick_name != ? ", sendID, sType, nickname).Updates( map[string]interface{}{"sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed") } @@ -378,14 +343,14 @@ func (d *DataBase) SuperGroupUpdateMsgSenderNickname(ctx context.Context, sendID func (d *DataBase) SuperGroupUpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where( "send_id = ? and session_type = ? and sender_face_url != ? ", sendID, sType, faceURL).Updates( map[string]interface{}{"sender_face_url": faceURL}).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) SuperGroupUpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, sendID, faceURL, nickname string, sessionType int, groupID string) error { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where( + return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where( "send_id = ? and session_type = ?", sendID, sessionType).Updates( map[string]interface{}{"sender_face_url": faceURL, "sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed") } @@ -394,30 +359,26 @@ func (d *DataBase) SuperGroupGetMsgSeqByClientMsgID(ctx context.Context, clientM d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seq uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("seq").Where("client_msg_id=?", clientMsgID).Take(&seq).Error, utils.GetSelfFuncName()+" failed") - return seq, err + return seq, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("seq").Where("client_msg_id=?", clientMsgID).Take(&seq).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) SuperGroupGetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) SuperGroupGetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } func (d *DataBase) SuperGroupGetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() var seqList []uint32 - err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") - return seqList, err + return seqList, errs.WrapMsg(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed") } diff --git a/pkg/db/super_group_model.go b/pkg/db/super_group_model.go index 811a7ca1c..6b9813831 100644 --- a/pkg/db/super_group_model.go +++ b/pkg/db/super_group_model.go @@ -20,28 +20,29 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) InsertSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error { d.superGroupMtx.Lock() defer d.superGroupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Create(groupInfo).Error, "InsertSuperGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Create(groupInfo).Error, "InsertSuperGroup failed") } func (d *DataBase) DeleteAllSuperGroup(ctx context.Context) error { d.superGroupMtx.Lock() defer d.superGroupMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&model_struct.LocalGroup{}).Error, "DeleteAllSuperGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&model_struct.LocalGroup{}).Error, "DeleteAllSuperGroup failed") } func (d *DataBase) GetSuperGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error) { d.superGroupMtx.Lock() defer d.superGroupMtx.Unlock() var g model_struct.LocalGroup - return &g, utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed") + return &g, errs.WrapMsg(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed") } func (d *DataBase) UpdateSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error { @@ -50,14 +51,14 @@ func (d *DataBase) UpdateSuperGroup(ctx context.Context, groupInfo *model_struct t := d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Select("*").Updates(*groupInfo) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.WrapMsg(t.Error, "") } func (d *DataBase) DeleteSuperGroup(ctx context.Context, groupID string) error { d.superGroupMtx.Lock() defer d.superGroupMtx.Unlock() localGroup := model_struct.LocalGroup{GroupID: groupID} - return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&localGroup).Error, "DeleteSuperGroup failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&localGroup).Error, "DeleteSuperGroup failed") } diff --git a/pkg/db/temp_cache_chat_log_model.go b/pkg/db/temp_cache_chat_log_model.go index b837b9651..a6f6590e6 100644 --- a/pkg/db/temp_cache_chat_log_model.go +++ b/pkg/db/temp_cache_chat_log_model.go @@ -19,18 +19,19 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) BatchInsertTempCacheMessageList(ctx context.Context, MessageList []*model_struct.TempCacheLocalChatLog) error { if MessageList == nil { return nil } - return utils.Wrap(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertTempCacheMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertTempCacheMessageList failed") } func (d *DataBase) InsertTempCacheMessage(ctx context.Context, Message *model_struct.TempCacheLocalChatLog) error { - return utils.Wrap(d.conn.WithContext(ctx).Create(Message).Error, "InsertTempCacheMessage failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(Message).Error, "InsertTempCacheMessage failed") } diff --git a/pkg/db/upload_model.go b/pkg/db/upload_model.go index 986c12836..5a3a5fc44 100644 --- a/pkg/db/upload_model.go +++ b/pkg/db/upload_model.go @@ -19,9 +19,10 @@ package db import ( "context" - "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "time" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/tools/errs" ) diff --git a/pkg/db/user_command.go b/pkg/db/user_command.go index ae6057086..2153a9151 100644 --- a/pkg/db/user_command.go +++ b/pkg/db/user_command.go @@ -19,8 +19,9 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "github.com/pkg/errors" ) @@ -38,7 +39,7 @@ func (d *DataBase) ProcessUserCommandAdd(ctx context.Context, command *model_str Ex: command.Ex, } - return utils.Wrap(d.conn.WithContext(ctx).Create(&userCommand).Error, "ProcessUserCommandAdd failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(&userCommand).Error, "ProcessUserCommandAdd failed") } // ProcessUserCommandUpdate updates an existing user command in the database. @@ -48,9 +49,9 @@ func (d *DataBase) ProcessUserCommandUpdate(ctx context.Context, command *model_ t := d.conn.WithContext(ctx).Model(command).Select("*").Updates(*command) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "") + return errs.WrapMsg(t.Error, "") } @@ -58,8 +59,7 @@ func (d *DataBase) ProcessUserCommandUpdate(ctx context.Context, command *model_ func (d *DataBase) ProcessUserCommandDelete(ctx context.Context, command *model_struct.LocalUserCommand) error { d.userMtx.Lock() defer d.userMtx.Unlock() - - return utils.Wrap(d.conn.WithContext(ctx).Where("type = ? AND uuid = ?", command.Type, command.Uuid).Delete(&model_struct.LocalUserCommand{}).Error, + return errs.WrapMsg(d.conn.WithContext(ctx).Where("type = ? AND uuid = ?", command.Type, command.Uuid).Delete(&model_struct.LocalUserCommand{}).Error, "ProcessUserCommandDelete failed") } @@ -67,8 +67,6 @@ func (d *DataBase) ProcessUserCommandDelete(ctx context.Context, command *model_ func (d *DataBase) ProcessUserCommandGetAll(ctx context.Context) ([]*model_struct.LocalUserCommand, error) { d.userMtx.RLock() defer d.userMtx.RUnlock() - var commands []*model_struct.LocalUserCommand - err := d.conn.WithContext(ctx).Find(&commands).Error - return commands, utils.Wrap(err, "ProcessUserCommandGetAll failed") + return commands, errs.WrapMsg(d.conn.WithContext(ctx).Find(&commands).Error, "ProcessUserCommandGetAll failed") } diff --git a/pkg/db/user_model.go b/pkg/db/user_model.go index 4e23cc7cf..eddbfeb14 100644 --- a/pkg/db/user_model.go +++ b/pkg/db/user_model.go @@ -20,15 +20,16 @@ package db import ( "context" "errors" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetLoginUser(ctx context.Context, userID string) (*model_struct.LocalUser, error) { d.userMtx.RLock() defer d.userMtx.RUnlock() var user model_struct.LocalUser - return &user, utils.Wrap(d.conn.WithContext(ctx).Where("user_id = ? ", userID).Take(&user).Error, "GetLoginUserInfo failed") + return &user, errs.WrapMsg(d.conn.WithContext(ctx).Where("user_id = ? ", userID).Take(&user).Error, "GetLoginUserInfo failed") } func (d *DataBase) UpdateLoginUser(ctx context.Context, user *model_struct.LocalUser) error { @@ -36,21 +37,21 @@ func (d *DataBase) UpdateLoginUser(ctx context.Context, user *model_struct.Local defer d.userMtx.Unlock() t := d.conn.WithContext(ctx).Model(user).Select("*").Updates(user) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateLoginUser failed") + return errs.WrapMsg(t.Error, "UpdateLoginUser failed") } func (d *DataBase) UpdateLoginUserByMap(ctx context.Context, user *model_struct.LocalUser, args map[string]interface{}) error { d.userMtx.Lock() defer d.userMtx.Unlock() t := d.conn.WithContext(ctx).Model(&user).Updates(args) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "UpdateColumnsConversation failed") + return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed") } func (d *DataBase) InsertLoginUser(ctx context.Context, user *model_struct.LocalUser) error { d.userMtx.Lock() defer d.userMtx.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Create(user).Error, "InsertLoginUser failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(user).Error, "InsertLoginUser failed") } diff --git a/pkg/db/work_moments_model.go b/pkg/db/work_moments_model.go index ac7139e39..b1d2c44f3 100644 --- a/pkg/db/work_moments_model.go +++ b/pkg/db/work_moments_model.go @@ -20,10 +20,11 @@ package db import ( "context" "errors" + "time" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" "gorm.io/gorm" - "time" ) func (d *DataBase) InsertWorkMomentsNotification(ctx context.Context, jsonDetail string) error { @@ -33,32 +34,30 @@ func (d *DataBase) InsertWorkMomentsNotification(ctx context.Context, jsonDetail JsonDetail: jsonDetail, CreateTime: time.Now().Unix(), } - return utils.Wrap(d.conn.WithContext(ctx).Create(workMomentsNotification).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(workMomentsNotification).Error, "") } func (d *DataBase) GetWorkMomentsNotification(ctx context.Context, offset, count int) (WorkMomentsNotifications []*model_struct.LocalWorkMomentsNotification, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() WorkMomentsNotifications = []*model_struct.LocalWorkMomentsNotification{} - err = utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Order("create_time DESC").Offset(offset).Limit(count).Find(&WorkMomentsNotifications).Error, "") - return WorkMomentsNotifications, err + return WorkMomentsNotifications, errs.WrapMsg(d.conn.WithContext(ctx).Table("local_work_moments_notification").Order("create_time DESC").Offset(offset).Limit(count).Find(&WorkMomentsNotifications).Error, "") } func (d *DataBase) GetWorkMomentsNotificationLimit(ctx context.Context, pageNumber, showNumber int) (WorkMomentsNotifications []*model_struct.LocalWorkMomentsNotification, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() WorkMomentsNotifications = []*model_struct.LocalWorkMomentsNotification{} - err = utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Select("json_detail").Find(WorkMomentsNotifications).Error, "") - return WorkMomentsNotifications, err + return WorkMomentsNotifications, errs.WrapMsg(d.conn.WithContext(ctx).Table("local_work_moments_notification").Select("json_detail").Find(WorkMomentsNotifications).Error, "") } func (d *DataBase) InitWorkMomentsNotificationUnreadCount(ctx context.Context) error { var n int64 - err := utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Count(&n).Error, "") + err := errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Count(&n).Error, "") if err == nil { if n == 0 { c := model_struct.LocalWorkMomentsNotificationUnreadCount{UnreadCount: 0} - return utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Create(c).Error, "IncrConversationUnreadCount failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Create(c).Error, "IncrConversationUnreadCount failed") } } return err @@ -70,27 +69,26 @@ func (d *DataBase) IncrWorkMomentsNotificationUnreadCount(ctx context.Context) e c := model_struct.LocalWorkMomentsNotificationUnreadCount{} t := d.conn.WithContext(ctx).Model(&c).Where("1=1").Update("unread_count", gorm.Expr("unread_count+?", 1)) if t.RowsAffected == 0 { - return utils.Wrap(errors.New("RowsAffected == 0"), "no update") + return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update") } - return utils.Wrap(t.Error, "IncrConversationUnreadCount failed") + return errs.WrapMsg(t.Error, "IncrConversationUnreadCount failed") } func (d *DataBase) MarkAllWorkMomentsNotificationAsRead(ctx context.Context) (err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Where("1=1").Updates(map[string]interface{}{"unread_count": 0}).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Where("1=1").Updates(map[string]interface{}{"unread_count": 0}).Error, "") } func (d *DataBase) GetWorkMomentsUnReadCount(ctx context.Context) (workMomentsNotificationUnReadCount model_struct.LocalWorkMomentsNotificationUnreadCount, err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() workMomentsNotificationUnReadCount = model_struct.LocalWorkMomentsNotificationUnreadCount{} - err = utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).First(&workMomentsNotificationUnReadCount).Error, "") - return workMomentsNotificationUnReadCount, err + return workMomentsNotificationUnReadCount, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).First(&workMomentsNotificationUnReadCount).Error, "") } func (d *DataBase) ClearWorkMomentsNotification(ctx context.Context) (err error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() - return utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Where("1=1").Delete(&model_struct.LocalWorkMomentsNotification{}).Error, "") + return errs.WrapMsg(d.conn.WithContext(ctx).Table("local_work_moments_notification").Where("1=1").Delete(&model_struct.LocalWorkMomentsNotification{}).Error, "") } diff --git a/pkg/db/working_group.go b/pkg/db/working_group.go index c4bf35658..5776fdda0 100644 --- a/pkg/db/working_group.go +++ b/pkg/db/working_group.go @@ -19,15 +19,16 @@ package db import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" - "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) GetJoinedWorkingGroupIDList(ctx context.Context) ([]string, error) { groupList, err := d.GetJoinedGroupListDB(ctx) if err != nil { - return nil, utils.Wrap(err, "") + return nil, errs.WrapMsg(err, "") } var groupIDList []string for _, v := range groupList { @@ -46,5 +47,5 @@ func (d *DataBase) GetJoinedWorkingGroupList(ctx context.Context) ([]*model_stru transfer = append(transfer, v) } } - return transfer, utils.Wrap(err, "GetJoinedSuperGroupList failed ") + return transfer, errs.WrapMsg(err, "GetJoinedSuperGroupList failed ") } From f3115112732b5dd5ee40b77f36376b24442718e1 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Tue, 25 Jun 2024 15:52:48 +0800 Subject: [PATCH 56/69] fix: update uncorrect log call args. --- test/t_conversation_msg.go | 46 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/t_conversation_msg.go b/test/t_conversation_msg.go index c0d1373f3..b1ff66d4a 100644 --- a/test/t_conversation_msg.go +++ b/test/t_conversation_msg.go @@ -435,7 +435,7 @@ func (g GetHistoryCallBack) OnError(errCode int32, errMsg string) { func (g GetHistoryCallBack) OnSuccess(data string) { g.Data = data - log.ZInfo(ctx, "get History success ", "operationID", g.OperationID, "data", data) + log.ZInfo(ctx, "get History success. ", "operationID", g.OperationID, "data", g.Data) } type SetAppBadgeCallBack struct { @@ -507,7 +507,7 @@ func (g GetMessageListReactionExtensionsCallBack) OnError(errCode int32, errMsg } func (g GetMessageListReactionExtensionsCallBack) OnSuccess(data string) { - log.ZInfo(ctx, g.OperationID, "GetMessageListReactionExtensionsCallBack success", "data", data) + log.ZInfo(ctx, g.OperationID, "GetMessageListReactionExtensionsCallBack success. data", data) } type GetHistoryReverseCallBack struct { @@ -519,7 +519,7 @@ func (g GetHistoryReverseCallBack) OnError(errCode int32, errMsg string) { } func (g GetHistoryReverseCallBack) OnSuccess(data string) { - log.ZInfo(ctx, g.OperationID, "GetHistoryReverseCallBack success", "data", data) + log.ZInfo(ctx, g.OperationID, "GetHistoryReverseCallBack success. data", data) } type SearchLocalMessagesCallBack struct { @@ -531,7 +531,7 @@ func (g SearchLocalMessagesCallBack) OnError(errCode int32, errMsg string) { } func (g SearchLocalMessagesCallBack) OnSuccess(data string) { - fmt.Println(g.OperationID, "SearchLocalMessagesCallBack success", "data", data) + fmt.Println(g.OperationID, "SearchLocalMessagesCallBack success. data", data) } type MsgListenerCallBak struct { @@ -545,8 +545,8 @@ func (m *MsgListenerCallBak) OnRecvOfflineNewMessage(message string) { } func (m *MsgListenerCallBak) OnRecvMessageExtensionsAdded(msgID string, reactionExtensionList string) { - fmt.Printf("OnRecvMessageExtensionsAdded", msgID, reactionExtensionList) - log.ZInfo(ctx, "internal", "OnRecvMessageExtensionsAdded", "msgID", msgID, "reactionExtensionList", reactionExtensionList) + fmt.Printf("OnRecvMessageExtensionsAdded %v %v", msgID, reactionExtensionList) + log.ZInfo(ctx, "internal OnRecvMessageExtensionsAdded", "msgID", msgID, "reactionExtensionList", reactionExtensionList) } func (m *MsgListenerCallBak) OnRecvGroupReadReceipt(groupMsgReceiptList string) { @@ -558,11 +558,11 @@ func (m *MsgListenerCallBak) OnNewRecvMessageRevoked(messageRevoked string) { } func (m *MsgListenerCallBak) OnRecvMessageExtensionsChanged(msgID string, reactionExtensionList string) { - log.ZInfo(ctx, "internal", "OnRecvMessageExtensionsChanged", "msgID", msgID, "reactionExtensionList", reactionExtensionList) + log.ZInfo(ctx, "internal OnRecvMessageExtensionsChanged", "msgID", msgID, "reactionExtensionList", reactionExtensionList) } func (m *MsgListenerCallBak) OnRecvMessageExtensionsDeleted(msgID string, reactionExtensionKeyList string) { - log.ZInfo(ctx, "internal", "OnRecvMessageExtensionsDeleted", "msgID", msgID, "reactionExtensionKeyList", reactionExtensionKeyList) + log.ZInfo(ctx, "internal OnRecvMessageExtensionsDeleted", "msgID", msgID, "reactionExtensionKeyList", reactionExtensionKeyList) } func (m *MsgListenerCallBak) OnRecvOnlineOnlyMessage(message string) { @@ -599,11 +599,11 @@ type TestSearchLocalMessages struct { } func (t TestSearchLocalMessages) OnError(errCode int32, errMsg string) { - log.ZInfo(ctx, t.OperationID, "SearchLocalMessages , OnError", "errCode", errCode, "errMsg", errMsg) + log.ZInfo(ctx, "SearchLocalMessages , OnError", "operationID", t.OperationID, "errCode", errCode, "errMsg", errMsg) } func (t TestSearchLocalMessages) OnSuccess(data string) { - log.ZInfo(ctx, t.OperationID, "SearchLocalMessages , OnSuccess", "data", data) + log.ZInfo(ctx, "SearchLocalMessages , OnSuccess", "operationID", t.OperationID, "data", data) } //funcation DoTestSearchLocalMessages() { @@ -623,11 +623,11 @@ type TestDeleteConversation struct { } func (t TestDeleteConversation) OnError(errCode int32, errMsg string) { - log.ZInfo(ctx, t.OperationID, "TestDeleteConversation , OnError", "errCode", errCode, "errMsg", errMsg) + log.ZInfo(ctx, "TestDeleteConversation , OnError", "operationID", t.OperationID, "errCode", errCode, "errMsg", errMsg) } func (t TestDeleteConversation) OnSuccess(data string) { - log.ZInfo(ctx, t.OperationID, "TestDeleteConversation , OnSuccess", "data", data) + log.ZInfo(ctx, "TestDeleteConversation , OnSuccess", "operationID", t.OperationID, "data", data) } func (m MsgListenerCallBak) OnRecvC2CReadReceipt(data string) { @@ -667,7 +667,7 @@ func (c *conversationCallBack) OnSyncServerFailed() { } func (c *conversationCallBack) OnNewConversation(conversationList string) { - log.ZInfo(ctx, "OnNewConversation returnList is", conversationList) + log.ZInfo(ctx, "OnNewConversation.", "returnList is", conversationList) } func (c *conversationCallBack) OnConversationChanged(conversationList string) { @@ -675,7 +675,7 @@ func (c *conversationCallBack) OnConversationChanged(conversationList string) { } func (c *conversationCallBack) OnTotalUnreadMessageCountChanged(totalUnreadCount int32) { - log.ZInfo(ctx, "OnTotalUnreadMessageCountChanged returnTotalUnreadCount is", totalUnreadCount) + log.ZInfo(ctx, "OnTotalUnreadMessageCountChanged. ", "returnTotalUnreadCount is", totalUnreadCount) } func (c *conversationCallBack) OnConversationUserInputStatusChanged(change string) { @@ -737,7 +737,7 @@ func DoTestSendMsg2(sendId, recvID string) { o := sdkws.OfflinePushInfo{} o.Title = "121313" o.Desc = "45464" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(&o), false) log.ZInfo(ctx, utils.GetSelfFuncName(), "success", "sendId", sendId, "recvID", recvID) // 修改此行 } @@ -751,7 +751,7 @@ func DoTestSendMsg2Group(sendId, groupID string, index int) { o := sdkws.OfflinePushInfo{} o.Title = "Title" o.Desc = "Desc" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, "", groupID, utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, "", groupID, utils.StructToJsonString(&o), false) log.ZInfo(ctx, utils.GetSelfFuncName(), "success") // 修改此行 } @@ -764,7 +764,7 @@ func DoTestSendMsg2GroupWithMessage(sendId, groupID string, message string) { o := sdkws.OfflinePushInfo{} o.Title = "Title" o.Desc = "Desc" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, "", groupID, utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, "", groupID, utils.StructToJsonString(&o), false) log.ZInfo(ctx, utils.GetSelfFuncName(), "success") // 修改此行 } @@ -778,7 +778,7 @@ func DoTestSendMsg2c2c(sendId, recvID string, index int) { o := sdkws.OfflinePushInfo{} o.Title = "Title" o.Desc = "Desc" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(&o), false) log.ZInfo(ctx, utils.GetSelfFuncName(), "success") // 修改此行 } @@ -815,7 +815,7 @@ func DoTestSendMsg(index int, sendId, recvID string, groupID string, idx string) testSendMsg.recvID = recvID testSendMsg.groupID = groupID testSendMsg.msgID = s.ClientMsgID - log.ZInfo(ctx, "SendMessage", "operationID", operationID, "sendId", sendId, "recvID", recvID, "groupID", groupID, "msgID", + log.ZInfo(ctx, "SendMessage", "operationID", testSendMsg.OperationID, "sendId", testSendMsg.sendID, "recvID", testSendMsg.recvID, "groupID", testSendMsg.groupID, "msgID", testSendMsg.msgID, "index", index) if recvID != "" { allLoginMgr[index].mgr.Conversation().SendMessage(ctx, s, recvID, "", &o, false) @@ -824,7 +824,7 @@ func DoTestSendMsg(index int, sendId, recvID string, groupID string, idx string) } SendMsgMapLock.Lock() defer SendMsgMapLock.Unlock() - x := SendRecvTime{SendTime: utils.GetCurrentTimestampByMill()} + x := SendRecvTime{SendTime: testSendMsg.sendTime} SendSuccAllMsg[testSendMsg.msgID] = &x } @@ -858,7 +858,7 @@ func DoTestSendImageMsg(recvID string) { o := sdkws.OfflinePushInfo{} o.Title = "121313" o.Desc = "45464" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(&o), false) } //funcation DotestUploadFile() { @@ -875,7 +875,7 @@ func DoTestSendOtherMsg(sendId, recvID string) { o := sdkws.OfflinePushInfo{} o.Title = "121313" o.Desc = "45464" - open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(&o), false) } func DoTestSendVideo(sendId, recvID string) { @@ -887,7 +887,7 @@ func DoTestSendVideo(sendId, recvID string) { o.Title = "121313" o.Desc = "45464" log.ZInfo(ctx, "SendMessage", "operationID", operationID, "message", s) - open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(o), false) + open_im_sdk.SendMessage(&testSendMsg, operationID, s, recvID, "", utils.StructToJsonString(&o), false) } type TestClearMsg struct { From be985bd96b9aaceca3df50e9190b09144d26a2fa Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Tue, 25 Jun 2024 21:30:21 +0800 Subject: [PATCH 57/69] feat: get group list add page function. --- internal/group/sdk.go | 3 +++ pkg/datafetcher/datafetcher.go | 8 +++++--- pkg/db/group_member_model.go | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 48535a7be..3821deb82 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -265,6 +265,9 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string if err != nil { return nil, err } + if len(serverGroupMember) == 0 { + return nil, nil + } return datautil.Batch(ServerGroupMemberToLocalGroupMember, serverGroupMember), nil }, ) diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go index cb7972ba9..0d449727e 100644 --- a/pkg/datafetcher/datafetcher.go +++ b/pkg/datafetcher/datafetcher.go @@ -86,12 +86,14 @@ func (ds *DataFetcher[T]) FetchMissingAndFillLocal(ctx context.Context, uids []s if err != nil { return nil, err } + if len(serverData) > 0 { + if err := ds.batchInsert(ctx, serverData); err != nil { + return nil, err + } - if err := ds.batchInsert(ctx, serverData); err != nil { - return nil, err + localData = append(localData, serverData...) } - localData = append(localData, serverData...) } return localData, nil diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 4f980fbc9..33436ae2d 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -194,7 +194,7 @@ func (d *DataBase) InsertGroupMember(ctx context.Context, groupMember *model_str func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList []*model_struct.LocalGroupMember) error { d.groupMtx.Lock() defer d.groupMtx.Unlock() - return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertMessageList failed") + return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertGroupMember failed") } func (d *DataBase) DeleteGroupMember(ctx context.Context, groupID, userID string) error { From 99c22a342b35f204c10143677b3556e65aa0063d Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:46:37 +0800 Subject: [PATCH 58/69] feat: get group list add page function. --- internal/group/group.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/group/group.go b/internal/group/group.go index 115d36847..f661c7d9c 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -97,6 +97,7 @@ func (g *Group) initSyncer() { }, }, g.conversationCh) case syncer.Delete: + local.MemberCount = 0 g.listener().OnJoinedGroupDeleted(utils.StructToJsonString(local)) case syncer.Update: log.ZInfo(ctx, "groupSyncer trigger update", "groupID", From d16b2d24f98d05171a1a9115349ccf9945fe9a0e Mon Sep 17 00:00:00 2001 From: icey-yu <1186114839@qq.com> Date: Wed, 26 Jun 2024 18:43:45 +0800 Subject: [PATCH 59/69] fix:is in group --- internal/group/sdk.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 3821deb82..a24dcdef3 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -320,17 +320,13 @@ func (g *Group) SearchGroupMembers(ctx context.Context, searchParam *sdk_params_ } func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { - groupList, err := g.db.GetJoinedGroupListDB(ctx) + _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) if err != nil { return false, err } - for _, localGroup := range groupList { - if localGroup.GroupID == groupID { - return true, nil - } - } - return false, nil + return true, nil } + func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, userIDList []string) error { if err := util.ApiPost(ctx, constant.InviteUserToGroupRouter, &group.InviteUserToGroupReq{GroupID: groupID, Reason: reason, InvitedUserIDs: userIDList}, nil); err != nil { return err From 6994376f7915374ccf55ba18e3269b9c307b77f7 Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:35:33 +0800 Subject: [PATCH 60/69] feat: get group list add page function. --- internal/group/sdk.go | 42 ++++++++++++++++++++++++++++++---- pkg/datafetcher/datafetcher.go | 28 +++++++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 3821deb82..f67677d9b 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -209,7 +209,7 @@ func (g *Group) GetSpecifiedGroupsInfo(ctx context.Context, groupIDs []string) ( return datautil.Batch(ServerGroupToLocalGroup, serverGroupInfo), nil }, ) - return dataFetcher.FetchMissingAndFillLocal(ctx, groupIDs) + return dataFetcher.FetchMissingAndCombineLocal(ctx, groupIDs) } func (g *Group) SearchGroups(ctx context.Context, param sdk_params_callback.SearchGroupsParam) ([]*model_struct.LocalGroup, error) { @@ -247,6 +247,25 @@ func (g *Group) GetGroupMemberListByJoinTimeFilter(ctx context.Context, groupID } func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) { + lvs, err := g.db.GetVersionSync(ctx, g.groupTableName(), g.loginUserID) + if err != nil { + return nil, err + } + if datautil.Contain(groupID, lvs.UIDList...) { + + _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) + if err != nil { + if errs.Unwrap(err) != gorm.ErrRecordNotFound { + return nil, err + } + err := g.IncrSyncGroupAndMember(ctx, groupID) + if err != nil { + return nil, err + } + } + } else { // If the user is no longer in the group, return nil immediately + return nil, nil + } dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupAndMemberVersionTableName(), @@ -276,13 +295,26 @@ func (g *Group) GetSpecifiedGroupMembersInfo(ctx context.Context, groupID string } func (g *Group) GetGroupMemberList(ctx context.Context, groupID string, filter, offset, count int32) ([]*model_struct.LocalGroupMember, error) { - _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) - if errs.Unwrap(err) == gorm.ErrRecordNotFound { - err := g.IncrSyncGroupAndMember(ctx, groupID) + lvs, err := g.db.GetVersionSync(ctx, g.groupTableName(), g.loginUserID) + if err != nil { + return nil, err + } + if datautil.Contain(groupID, lvs.UIDList...) { + + _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) if err != nil { - return nil, err + if errs.Unwrap(err) != gorm.ErrRecordNotFound { + return nil, err + } + err := g.IncrSyncGroupAndMember(ctx, groupID) + if err != nil { + return nil, err + } } + } else { // If the user is no longer in the group, return nil immediately + return nil, nil } + dataFetcher := datafetcher.NewDataFetcher( g.db, g.groupAndMemberVersionTableName(), diff --git a/pkg/datafetcher/datafetcher.go b/pkg/datafetcher/datafetcher.go index 0d449727e..1de250384 100644 --- a/pkg/datafetcher/datafetcher.go +++ b/pkg/datafetcher/datafetcher.go @@ -98,3 +98,31 @@ func (ds *DataFetcher[T]) FetchMissingAndFillLocal(ctx context.Context, uids []s return localData, nil } + +// FetchMissingAndCombineLocal fetches missing data from the server and combines it with local data without inserting it into the local database +func (ds *DataFetcher[T]) FetchMissingAndCombineLocal(ctx context.Context, uids []string) ([]T, error) { + localData, err := ds.FetchFromLocal(ctx, uids) + if err != nil { + return nil, err + } + + localUIDSet := datautil.SliceSetAny(localData, ds.Key) + + var missingUIDs []string + for _, uid := range uids { + if _, found := localUIDSet[uid]; !found { + missingUIDs = append(missingUIDs, uid) + } + } + + if len(missingUIDs) > 0 { + serverData, err := ds.fetchFromServer(ctx, missingUIDs) + if err != nil { + return nil, err + } + // Combine local data with server data + localData = append(localData, serverData...) + } + + return localData, nil +} From 5e51f9fd95a878a2eec01d38eb992e760c5a771d Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:32:08 +0800 Subject: [PATCH 61/69] feat: get group list add page function. --- .../conversation_notification.go | 3 +- internal/conversation_msg/sync.go | 8 ++--- pkg/syncer/syncer.go | 36 ++++++++++++------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 11cc42d4d..84305e64f 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -73,7 +73,7 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } syncFunctions := []func(c context.Context) error{ - c.group.SyncAllJoinedGroupsAndMembers, c.friend.IncrSyncFriends, + c.group.SyncAllJoinedGroupsAndMembers, c.friend.IncrSyncFriends, c.SyncAllConversations, } for _, syncFunc := range syncFunctions { @@ -92,7 +92,6 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { case constant.MsgSyncEnd: log.ZDebug(ctx, "MsgSyncEnd", "time", time.Since(c.startTime).Milliseconds()) defer c.ConversationListener().OnSyncServerFinish() - go c.SyncAllConversations(ctx) } for conversationID, msgs := range allMsg { diff --git a/internal/conversation_msg/sync.go b/internal/conversation_msg/sync.go index b2a289605..ec87f674d 100644 --- a/internal/conversation_msg/sync.go +++ b/internal/conversation_msg/sync.go @@ -26,7 +26,7 @@ import ( "github.com/openimsdk/tools/log" ) -func (c *Conversation) SyncConversationsAndTriggerCallback(ctx context.Context, conversationsOnServer []*model_struct.LocalConversation) error { +func (c *Conversation) SyncConversationsAndTriggerCallback(ctx context.Context, conversationsOnServer []*model_struct.LocalConversation, skipNotice bool) error { conversationsOnLocal, err := c.db.GetAllConversations(ctx) if err != nil { return err @@ -39,7 +39,7 @@ func (c *Conversation) SyncConversationsAndTriggerCallback(ctx context.Context, c.doUpdateConversation(common.Cmd2Value{Value: common.UpdateConNode{ConID: server.ConversationID, Action: constant.ConChange, Args: []string{server.ConversationID}}}) } return nil - }, true); err != nil { + }, true, skipNotice); err != nil { return err } return nil @@ -50,7 +50,7 @@ func (c *Conversation) SyncConversations(ctx context.Context, conversationIDs [] if err != nil { return err } - return c.SyncConversationsAndTriggerCallback(ctx, conversationsOnServer) + return c.SyncConversationsAndTriggerCallback(ctx, conversationsOnServer, false) } func (c *Conversation) SyncAllConversations(ctx context.Context) error { @@ -60,7 +60,7 @@ func (c *Conversation) SyncAllConversations(ctx context.Context) error { return err } log.ZDebug(ctx, "get server cost time", "cost time", time.Since(ccTime), "conversation on server", conversationsOnServer) - return c.SyncConversationsAndTriggerCallback(ctx, conversationsOnServer) + return c.SyncConversationsAndTriggerCallback(ctx, conversationsOnServer, true) } func (c *Conversation) SyncAllConversationHashReadSeqs(ctx context.Context) error { diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index d002276f5..a2ac0aaf2 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -243,9 +243,13 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData } }() skipDeletion := false + skipNotice := false if len(skipDeletionAndNotice) > 0 { skipDeletion = skipDeletionAndNotice[0] } + if len(skipDeletionAndNotice) > 1 { + skipNotice = skipDeletionAndNotice[1] + } // If both server and local data are empty, log and return. if len(serverData) == 0 && len(localData) == 0 { @@ -271,9 +275,11 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData log.ZError(ctx, "sync insert failed", err, "type", s.ts, "server", server, "local", local) return err } - if err := s.onNotice(ctx, Insert, server, local, notice); err != nil { - log.ZError(ctx, "sync notice insert failed", err, "type", s.ts, "server", server, "local", local) - return err + if !skipNotice { + if err := s.onNotice(ctx, Insert, server, local, notice); err != nil { + log.ZError(ctx, "sync notice insert failed", err, "type", s.ts, "server", server, "local", local) + return err + } } continue } @@ -283,9 +289,11 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData // If the local and server items are equal, notify and continue. if s.eq(server, local) { - if err := s.onNotice(ctx, Unchanged, local, server, notice); err != nil { - log.ZError(ctx, "sync notice unchanged failed", err, "type", s.ts, "server", server, "local", local) - return err + if !skipNotice { + if err := s.onNotice(ctx, Unchanged, local, server, notice); err != nil { + log.ZError(ctx, "sync notice unchanged failed", err, "type", s.ts, "server", server, "local", local) + return err + } } continue } @@ -296,9 +304,11 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData log.ZError(ctx, "sync update failed", err, "type", s.ts, "server", server, "local", local) return err } - if err := s.onNotice(ctx, Update, server, local, notice); err != nil { - log.ZError(ctx, "sync notice update failed", err, "type", s.ts, "server", server, "local", local) - return err + if !skipNotice { + if err := s.onNotice(ctx, Update, server, local, notice); err != nil { + log.ZError(ctx, "sync notice update failed", err, "type", s.ts, "server", server, "local", local) + return err + } } } @@ -315,9 +325,11 @@ func (s *Syncer[T, RESP, V]) Sync(ctx context.Context, serverData []T, localData return err } var server T - if err := s.onNotice(ctx, Delete, server, local, notice); err != nil { - log.ZError(ctx, "sync notice delete failed", err, "type", s.ts, "local", local) - return err + if !skipNotice { + if err := s.onNotice(ctx, Delete, server, local, notice); err != nil { + log.ZError(ctx, "sync notice delete failed", err, "type", s.ts, "local", local) + return err + } } } return nil From 1a470ae93b8fa717a5c5450e761a0aa2660ae1a3 Mon Sep 17 00:00:00 2001 From: icey-yu <1186114839@qq.com> Date: Thu, 27 Jun 2024 17:45:00 +0800 Subject: [PATCH 62/69] fix:is in group --- internal/group/sdk.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index a24dcdef3..37bca7a7b 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -17,6 +17,7 @@ package group import ( "context" "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/mcontext" "gorm.io/gorm" "time" @@ -320,11 +321,16 @@ func (g *Group) SearchGroupMembers(ctx context.Context, searchParam *sdk_params_ } func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { - _, err := g.db.GetVersionSync(ctx, g.groupAndMemberVersionTableName(), groupID) + groupIDs, err := g.db.GetVersionSync(ctx, g.groupTableName(), mcontext.GetOpUserID(ctx)) if err != nil { return false, err } - return true, nil + for i := range groupIDs.UIDList { + if groupIDs.UIDList[i] == groupID { + return true, nil + } + } + return false, nil } func (g *Group) InviteUserToGroup(ctx context.Context, groupID, reason string, userIDList []string) error { From 49581697a47b4c285e20beb9365387dba8576f90 Mon Sep 17 00:00:00 2001 From: icey-yu <1186114839@qq.com> Date: Thu, 27 Jun 2024 17:47:19 +0800 Subject: [PATCH 63/69] fix:is in group --- internal/group/sdk.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/internal/group/sdk.go b/internal/group/sdk.go index 37bca7a7b..f27f26897 100644 --- a/internal/group/sdk.go +++ b/internal/group/sdk.go @@ -17,7 +17,6 @@ package group import ( "context" "github.com/openimsdk/tools/errs" - "github.com/openimsdk/tools/mcontext" "gorm.io/gorm" "time" @@ -321,14 +320,12 @@ func (g *Group) SearchGroupMembers(ctx context.Context, searchParam *sdk_params_ } func (g *Group) IsJoinGroup(ctx context.Context, groupID string) (bool, error) { - groupIDs, err := g.db.GetVersionSync(ctx, g.groupTableName(), mcontext.GetOpUserID(ctx)) + groupIDs, err := g.db.GetVersionSync(ctx, g.groupTableName(), g.loginUserID) if err != nil { return false, err } - for i := range groupIDs.UIDList { - if groupIDs.UIDList[i] == groupID { - return true, nil - } + if datautil.Contain(groupID, groupIDs.UIDList...) { + return true, nil } return false, nil } From 52b5f50f7f3b50ce512269bebc8639e54f30ed14 Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Fri, 28 Jun 2024 10:05:24 +0800 Subject: [PATCH 64/69] optimize large sessions blocking in login. --- internal/interaction/msg_sync.go | 48 ++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index 43475b716..7640ab714 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -17,6 +17,8 @@ package interaction import ( "context" "strings" + "sync" + "time" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -77,15 +79,51 @@ func (m *MsgSyncer) loadSeq(ctx context.Context) error { if len(conversationIDList) == 0 { m.reinstalled = true } - //TODO With a large number of sessions, this could potentially cause blocking and needs optimization. + + // TODO With a large number of sessions, this could potentially cause blocking and needs optimization. + type SyncedSeq struct { + ConversationID string + MaxSyncedSeq int64 + Err error + } + concurrency := 10 + t2 := time.Now() + SyncedSeqs := make(chan SyncedSeq, len(conversationIDList)) + sem := make(chan struct{}, concurrency) + + var wg sync.WaitGroup for _, v := range conversationIDList { - maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, v) - if err != nil { - log.ZError(ctx, "get group normal seq failed", err, "conversationID", v) + wg.Add(1) + sem <- struct{}{} // Acquire a token + go func(conversationID string) { + defer wg.Done() + defer func() { <-sem }() // Release the token + + maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, conversationID) + SyncedSeqs <- SyncedSeq{ + ConversationID: conversationID, + MaxSyncedSeq: maxSyncedSeq, + Err: err, + } + }(v) + log.ZDebug(ctx, "goroutine done.", "goroutine cost time", time.Since(t2)) + } + + // Close the results channel once all goroutines have finished + go func() { + wg.Wait() + close(SyncedSeqs) + }() + + // Collect the results + for res := range SyncedSeqs { + if res.Err != nil { + log.ZError(ctx, "get group normal seq failed", res.Err, "conversationID", res.ConversationID) } else { - m.syncedMaxSeqs[v] = maxSyncedSeq + m.syncedMaxSeqs[res.ConversationID] = res.MaxSyncedSeq } } + notificationSeqs, err := m.db.GetNotificationAllSeqs(ctx) if err != nil { log.ZError(ctx, "get notification seq failed", err) From 39d69d0349797b0e4287c273c67ce131e725dcfc Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:45:56 +0800 Subject: [PATCH 65/69] fix: reinstall app sync data split. --- .../conversation_notification.go | 79 +++++++++++++++---- .../conversation_msg/message_controller.go | 2 +- internal/conversation_msg/sync.go | 35 +++++++- internal/friend/sync.go | 45 +++++++++++ internal/group/sync.go | 28 +++++++ internal/interaction/msg_sync.go | 58 ++++++++++---- internal/user/sync.go | 35 +++++++- open_im_sdk/em.go | 12 ++- open_im_sdk_callback/callback_client.go | 8 +- pkg/common/trigger_channel.go | 20 ++--- pkg/constant/constant.go | 2 + pkg/db/db_interface/databse.go | 1 + pkg/db/notification_model.go | 7 ++ test/t_conversation_msg.go | 6 +- 14 files changed, 274 insertions(+), 64 deletions(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 84305e64f..68f09c848 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -38,7 +38,6 @@ func (c *Conversation) Work(c2v common.Cmd2Value) { switch c2v.Cmd { case constant.CmdNewMsgCome: c.doMsgNew(c2v) - case constant.CmdSuperGroupMsgCome: case constant.CmdUpdateConversation: c.doUpdateConversation(c2v) case constant.CmdUpdateMessage: @@ -54,26 +53,54 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { allMsg := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).Msgs syncFlag := c2v.Value.(sdk_struct.CmdNewMsgComeToConversation).SyncFlag switch syncFlag { - case constant.MsgSyncBegin: + case constant.AppDataSyncStart: + log.ZDebug(ctx, "AppDataSyncStart") c.startTime = time.Now() - c.ConversationListener().OnSyncServerStart() - if err := c.SyncAllConversationHashReadSeqs(ctx); err != nil { - log.ZError(ctx, "SyncConversationHashReadSeqs err", err) + c.ConversationListener().OnSyncServerStart(true) + syncFunctions := []func(c context.Context) error{ + c.SyncAllConversationHashReadSeqs, + c.user.SyncLoginUserInfoWithoutNotice, + c.friend.SyncAllBlackListWithoutNotice, + c.friend.SyncAllFriendApplicationWithoutNotice, + c.friend.SyncAllSelfFriendApplicationWithoutNotice, + c.group.SyncAllAdminGroupApplicationWithoutNotice, + c.group.SyncAllSelfGroupApplicationWithoutNotice, + c.user.SyncAllCommandWithoutNotice, + c.group.SyncAllJoinedGroupsAndMembers, + c.friend.IncrSyncFriends, + c.SyncAllConversationsWithoutNotice, } + totalFunctions := len(syncFunctions) + for i, syncFunc := range syncFunctions { + funcName := runtime.FuncForPC(reflect.ValueOf(syncFunc).Pointer()).Name() + startTime := time.Now() + err := syncFunc(ctx) + duration := time.Since(startTime) + if err != nil { + log.ZWarn(ctx, fmt.Sprintf("%s sync err", funcName), err, "duration", duration.Seconds()) + } else { + log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration.Seconds()) + } + progress := int(float64(i+1) / float64(totalFunctions) * 100) + if progress == 0 { + progress = 1 + } + c.ConversationListener().OnSyncServerProgress(progress) + } + case constant.AppDataSyncFinish: + log.ZDebug(ctx, "AppDataSyncFinish", "time", time.Since(c.startTime).Milliseconds()) + c.ConversationListener().OnSyncServerFailed(true) + case constant.MsgSyncBegin: + log.ZDebug(ctx, "MsgSyncBegin") + c.startTime = time.Now() + c.ConversationListener().OnSyncServerStart(false) //clear SubscriptionStatusMap c.user.OnlineStatusCache.DeleteAll() - for _, syncFunc := range []func(c context.Context) error{ - c.user.SyncLoginUserInfo, - c.friend.SyncAllBlackList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, - c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, - } { - go func(syncFunc func(c context.Context) error) { - _ = syncFunc(ctx) - }(syncFunc) - } syncFunctions := []func(c context.Context) error{ - c.group.SyncAllJoinedGroupsAndMembers, c.friend.IncrSyncFriends, c.SyncAllConversations, + c.SyncAllConversationHashReadSeqs, + c.group.SyncAllJoinedGroupsAndMembers, + c.friend.IncrSyncFriends, } for _, syncFunc := range syncFunctions { @@ -87,11 +114,29 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration.Seconds()) } } + for _, syncFunc := range []func(c context.Context) error{ + c.user.SyncLoginUserInfo, + c.friend.SyncAllBlackList, c.friend.SyncAllFriendApplication, c.friend.SyncAllSelfFriendApplication, + c.group.SyncAllAdminGroupApplication, c.group.SyncAllSelfGroupApplication, c.user.SyncAllCommand, c.SyncAllConversations, + } { + go func(syncFunc func(c context.Context) error) { + funcName := runtime.FuncForPC(reflect.ValueOf(syncFunc).Pointer()).Name() + startTime := time.Now() + err := syncFunc(ctx) + duration := time.Since(startTime) + if err != nil { + log.ZWarn(ctx, fmt.Sprintf("%s sync err", funcName), err, "duration", duration.Seconds()) + } else { + log.ZDebug(ctx, fmt.Sprintf("%s completed successfully", funcName), "duration", duration.Seconds()) + } + }(syncFunc) + } + case constant.MsgSyncFailed: - c.ConversationListener().OnSyncServerFailed() + c.ConversationListener().OnSyncServerFailed(false) case constant.MsgSyncEnd: log.ZDebug(ctx, "MsgSyncEnd", "time", time.Since(c.startTime).Milliseconds()) - defer c.ConversationListener().OnSyncServerFinish() + c.ConversationListener().OnSyncServerFinish(false) } for conversationID, msgs := range allMsg { diff --git a/internal/conversation_msg/message_controller.go b/internal/conversation_msg/message_controller.go index 59678a3fb..3b413e96b 100644 --- a/internal/conversation_msg/message_controller.go +++ b/internal/conversation_msg/message_controller.go @@ -50,7 +50,7 @@ func (m *MessageController) BatchUpdateMessageList(ctx context.Context, updateMs latestMsg := &sdk_struct.MsgStruct{} if err := json.Unmarshal([]byte(conversation.LatestMsg), latestMsg); err != nil { log.ZError(ctx, "Unmarshal err", err, "conversationID", - conversationID, "latestMsg", conversation.LatestMsg) + conversationID, "latestMsg", conversation.LatestMsg, "messages", messages) continue } for _, v := range messages { diff --git a/internal/conversation_msg/sync.go b/internal/conversation_msg/sync.go index ec87f674d..bfb6261f7 100644 --- a/internal/conversation_msg/sync.go +++ b/internal/conversation_msg/sync.go @@ -54,6 +54,16 @@ func (c *Conversation) SyncConversations(ctx context.Context, conversationIDs [] } func (c *Conversation) SyncAllConversations(ctx context.Context) error { + ccTime := time.Now() + conversationsOnServer, err := c.getServerConversationList(ctx) + if err != nil { + return err + } + log.ZDebug(ctx, "get server cost time", "cost time", time.Since(ccTime), "conversation on server", conversationsOnServer) + return c.SyncConversationsAndTriggerCallback(ctx, conversationsOnServer, false) +} + +func (c *Conversation) SyncAllConversationsWithoutNotice(ctx context.Context) error { ccTime := time.Now() conversationsOnServer, err := c.getServerConversationList(ctx) if err != nil { @@ -64,25 +74,34 @@ func (c *Conversation) SyncAllConversations(ctx context.Context) error { } func (c *Conversation) SyncAllConversationHashReadSeqs(ctx context.Context) error { + startTime := time.Now() log.ZDebug(ctx, "start SyncConversationHashReadSeqs") + seqs, err := c.getServerHasReadAndMaxSeqs(ctx) if err != nil { return err } + log.ZDebug(ctx, "getServerHasReadAndMaxSeqs completed", "duration", time.Since(startTime).Seconds()) + if len(seqs) == 0 { return nil } var conversationChangedIDs []string var conversationIDsNeedSync []string + stepStartTime := time.Now() conversationsOnLocal, err := c.db.GetAllConversations(ctx) if err != nil { log.ZWarn(ctx, "get all conversations err", err) return err } + log.ZDebug(ctx, "GetAllConversations completed", "duration", time.Since(stepStartTime).Seconds()) + conversationsOnLocalMap := datautil.SliceToMap(conversationsOnLocal, func(e *model_struct.LocalConversation) string { return e.ConversationID }) + + stepStartTime = time.Now() for conversationID, v := range seqs { var unreadCount int32 c.maxSeqRecorder.Set(conversationID, v.MaxSeq) @@ -104,18 +123,24 @@ func (c *Conversation) SyncAllConversationHashReadSeqs(ctx context.Context) erro } else { conversationIDsNeedSync = append(conversationIDsNeedSync, conversationID) } - } + log.ZDebug(ctx, "Process seqs completed", "duration", time.Since(stepStartTime).Seconds()) + if len(conversationIDsNeedSync) > 0 { + stepStartTime = time.Now() conversationsOnServer, err := c.getServerConversationsByIDs(ctx, conversationIDsNeedSync) if err != nil { log.ZWarn(ctx, "getServerConversationsByIDs err", err, "conversationIDs", conversationIDsNeedSync) return err } + log.ZDebug(ctx, "getServerConversationsByIDs completed", "duration", time.Since(stepStartTime).Seconds()) + + stepStartTime = time.Now() if err := c.batchAddFaceURLAndName(ctx, conversationsOnServer...); err != nil { log.ZWarn(ctx, "batchAddFaceURLAndName err", err, "conversationsOnServer", conversationsOnServer) return err } + log.ZDebug(ctx, "batchAddFaceURLAndName completed", "duration", time.Since(stepStartTime).Seconds()) for _, conversation := range conversationsOnServer { var unreadCount int32 @@ -132,17 +157,23 @@ func (c *Conversation) SyncAllConversationHashReadSeqs(ctx context.Context) erro conversation.UnreadCount = unreadCount conversation.HasReadSeq = v.HasReadSeq } + + stepStartTime = time.Now() err = c.db.BatchInsertConversationList(ctx, conversationsOnServer) if err != nil { log.ZWarn(ctx, "BatchInsertConversationList err", err, "conversationsOnServer", conversationsOnServer) } - + log.ZDebug(ctx, "BatchInsertConversationList completed", "duration", time.Since(stepStartTime).Seconds()) } log.ZDebug(ctx, "update conversations", "conversations", conversationChangedIDs) if len(conversationChangedIDs) > 0 { + stepStartTime = time.Now() common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.ConChange, Args: conversationChangedIDs}, c.GetCh()) common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.TotalUnreadMessageChanged}, c.GetCh()) + log.ZDebug(ctx, "TriggerCmdUpdateConversation completed", "duration", time.Since(stepStartTime).Seconds()) } + + log.ZDebug(ctx, "SyncAllConversationHashReadSeqs completed", "totalDuration", time.Since(startTime).Seconds()) return nil } diff --git a/internal/friend/sync.go b/internal/friend/sync.go index 21caef624..4fd297995 100644 --- a/internal/friend/sync.go +++ b/internal/friend/sync.go @@ -61,6 +61,22 @@ func (f *Friend) SyncAllSelfFriendApplication(ctx context.Context) error { return f.requestSendSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) } +func (f *Friend) SyncAllSelfFriendApplicationWithoutNotice(ctx context.Context) error { + req := &friend.GetPaginationFriendsApplyFromReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} + fn := func(resp *friend.GetPaginationFriendsApplyFromResp) []*sdkws.FriendRequest { + return resp.FriendRequests + } + requests, err := util.GetPageAll(ctx, constant.GetSelfFriendApplicationListRouter, req, fn) + if err != nil { + return err + } + localData, err := f.db.GetSendFriendApplication(ctx) + if err != nil { + return err + } + return f.requestSendSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil, false, true) +} + // recv func (f *Friend) SyncAllFriendApplication(ctx context.Context) error { req := &friend.GetPaginationFriendsApplyToReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} @@ -75,6 +91,19 @@ func (f *Friend) SyncAllFriendApplication(ctx context.Context) error { } return f.requestRecvSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil) } +func (f *Friend) SyncAllFriendApplicationWithoutNotice(ctx context.Context) error { + req := &friend.GetPaginationFriendsApplyToReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} + fn := func(resp *friend.GetPaginationFriendsApplyToResp) []*sdkws.FriendRequest { return resp.FriendRequests } + requests, err := util.GetPageAll(ctx, constant.GetFriendApplicationListRouter, req, fn) + if err != nil { + return err + } + localData, err := f.db.GetRecvFriendApplication(ctx) + if err != nil { + return err + } + return f.requestRecvSyncer.Sync(ctx, datautil.Batch(ServerFriendRequestToLocalFriendRequest, requests), localData, nil, false, true) +} func (f *Friend) SyncAllFriendList(ctx context.Context) error { t := time.Now() @@ -171,6 +200,22 @@ func (f *Friend) SyncAllBlackList(ctx context.Context) error { return f.blockSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil) } +func (f *Friend) SyncAllBlackListWithoutNotice(ctx context.Context) error { + req := &friend.GetPaginationBlacksReq{UserID: f.loginUserID, Pagination: &sdkws.RequestPagination{}} + fn := func(resp *friend.GetPaginationBlacksResp) []*sdkws.BlackInfo { return resp.Blacks } + serverData, err := util.GetPageAll(ctx, constant.GetBlackListRouter, req, fn) + if err != nil { + return err + } + log.ZDebug(ctx, "black from server", "data", serverData) + localData, err := f.db.GetBlackListDB(ctx) + if err != nil { + return err + } + log.ZDebug(ctx, "black from local", "data", localData) + return f.blockSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil, false, true) +} + func (f *Friend) GetDesignatedFriends(ctx context.Context, friendIDs []string) ([]*sdkws.FriendInfo, error) { resp := &friend.GetDesignatedFriendsResp{} if err := util.ApiPost(ctx, constant.GetDesignatedFriendsRouter, &friend.GetDesignatedFriendsReq{OwnerUserID: f.loginUserID, FriendUserIDs: friendIDs}, &resp); err != nil { diff --git a/internal/group/sync.go b/internal/group/sync.go index 16b338cdf..5ca7513f2 100644 --- a/internal/group/sync.go +++ b/internal/group/sync.go @@ -246,6 +246,22 @@ func (g *Group) SyncAllSelfGroupApplication(ctx context.Context) error { return nil } +func (g *Group) SyncAllSelfGroupApplicationWithoutNotice(ctx context.Context) error { + list, err := g.GetServerSelfGroupApplication(ctx) + if err != nil { + return err + } + localData, err := g.db.GetSendGroupApplication(ctx) + if err != nil { + return err + } + if err := g.groupRequestSyncer.Sync(ctx, datautil.Batch(ServerGroupRequestToLocalGroupRequest, list), localData, nil, false, true); err != nil { + return err + } + // todo + return nil +} + func (g *Group) SyncSelfGroupApplications(ctx context.Context, groupIDs ...string) error { return g.SyncAllSelfGroupApplication(ctx) } @@ -262,6 +278,18 @@ func (g *Group) SyncAllAdminGroupApplication(ctx context.Context) error { return g.groupAdminRequestSyncer.Sync(ctx, datautil.Batch(ServerGroupRequestToLocalAdminGroupRequest, requests), localData, nil) } +func (g *Group) SyncAllAdminGroupApplicationWithoutNotice(ctx context.Context) error { + requests, err := g.GetServerAdminGroupApplicationList(ctx) + if err != nil { + return err + } + localData, err := g.db.GetAdminGroupApplication(ctx) + if err != nil { + return err + } + return g.groupAdminRequestSyncer.Sync(ctx, datautil.Batch(ServerGroupRequestToLocalAdminGroupRequest, requests), localData, nil, false, true) +} + func (g *Group) SyncAdminGroupApplications(ctx context.Context, groupIDs ...string) error { return g.SyncAllAdminGroupApplication(ctx) } diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index 43475b716..58f9a503b 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -16,6 +16,7 @@ package interaction import ( "context" + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "strings" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" @@ -148,15 +149,31 @@ func (m *MsgSyncer) compareSeqsAndBatchSync(ctx context.Context, maxSeqToSync ma messagesSeqMap[conversationID] = seq } } + + var notificationSeqs []*model_struct.NotificationSeqs + for conversationID, seq := range notificationsSeqMap { - err := m.db.SetNotificationSeq(ctx, conversationID, seq) - if err != nil { - log.ZWarn(ctx, "SetNotificationSeq err", err, "conversationID", conversationID, "seq", seq) - continue - } else { - m.syncedMaxSeqs[conversationID] = seq - } + notificationSeqs = append(notificationSeqs, &model_struct.NotificationSeqs{ + ConversationID: conversationID, + Seq: seq, + }) + m.syncedMaxSeqs[conversationID] = seq } + + err := m.db.BatchInsertNotificationSeq(ctx, notificationSeqs) + if err != nil { + log.ZWarn(ctx, "BatchInsertNotificationSeq err", err) + } + + //for conversationID, seq := range notificationsSeqMap { + // err := m.db.SetNotificationSeq(ctx, conversationID, seq) + // if err != nil { + // log.ZWarn(ctx, "SetNotificationSeq err", err, "conversationID", conversationID, "seq", seq) + // continue + // } else { + // m.syncedMaxSeqs[conversationID] = seq + // } + //} for conversationID, maxSeq := range messagesSeqMap { if syncedMaxSeq, ok := m.syncedMaxSeqs[conversationID]; ok { if maxSeq > syncedMaxSeq { @@ -217,7 +234,12 @@ func (m *MsgSyncer) pushTriggerAndSync(ctx context.Context, pullMsgs map[string] // Called after successful reconnection to synchronize the latest message func (m *MsgSyncer) doConnected(ctx context.Context) { - common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.MsgSyncBegin}, m.conversationCh) + reinstalled := m.reinstalled + if reinstalled { + common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.AppDataSyncStart}, m.conversationCh) + } else { + common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.MsgSyncBegin}, m.conversationCh) + } var resp sdkws.GetMaxSeqResp if err := m.longConnMgr.SendReqWaitResp(m.ctx, &sdkws.GetMaxSeqReq{UserID: m.loginUserID}, constant.GetNewestSeq, &resp); err != nil { log.ZError(m.ctx, "get max seq error", err) @@ -227,7 +249,11 @@ func (m *MsgSyncer) doConnected(ctx context.Context) { log.ZDebug(m.ctx, "get max seq success", "resp", resp) } m.compareSeqsAndBatchSync(ctx, resp.MaxSeqs, connectPullNums) - common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.MsgSyncEnd}, m.conversationCh) + if reinstalled { + common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.AppDataSyncFinish}, m.conversationCh) + } else { + common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.MsgSyncEnd}, m.conversationCh) + } } func IsNotification(conversationID string) bool { @@ -363,24 +389,24 @@ func (m *MsgSyncer) syncMsgBySeqs(ctx context.Context, conversationID string, se // triggers a conversation with a new message. func (m *MsgSyncer) triggerConversation(ctx context.Context, msgs map[string]*sdkws.PullMsgs) error { - if len(msgs) >= 0 { + if len(msgs) > 0 { err := common.TriggerCmdNewMsgCome(ctx, sdk_struct.CmdNewMsgComeToConversation{Msgs: msgs}, m.conversationCh) if err != nil { log.ZError(ctx, "triggerCmdNewMsgCome err", err, "msgs", msgs) } log.ZDebug(ctx, "triggerConversation", "msgs", msgs) return err + } else { + log.ZDebug(ctx, "triggerConversation is nil", "msgs", msgs) } return nil } func (m *MsgSyncer) triggerNotification(ctx context.Context, msgs map[string]*sdkws.PullMsgs) error { - if len(msgs) >= 0 { - err := common.TriggerCmdNotification(ctx, sdk_struct.CmdNewMsgComeToConversation{Msgs: msgs}, m.conversationCh) - if err != nil { - log.ZError(ctx, "triggerCmdNewMsgCome err", err, "msgs", msgs) - } - return err + if len(msgs) > 0 { + common.TriggerCmdNotification(ctx, sdk_struct.CmdNewMsgComeToConversation{Msgs: msgs}, m.conversationCh) + } else { + log.ZDebug(ctx, "triggerNotification is nil", "msgs", msgs) } return nil diff --git a/internal/user/sync.go b/internal/user/sync.go index e3fd118c0..90b6f405a 100644 --- a/internal/user/sync.go +++ b/internal/user/sync.go @@ -22,10 +22,9 @@ import ( "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" userPb "github.com/openimsdk/protocol/user" - "github.com/openimsdk/tools/utils/datautil" - "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" "gorm.io/gorm" ) @@ -45,6 +44,22 @@ func (u *User) SyncLoginUserInfo(ctx context.Context) error { log.ZDebug(ctx, "SyncLoginUserInfo", "remoteUser", remoteUser, "localUser", localUser) return u.userSyncer.Sync(ctx, []*model_struct.LocalUser{remoteUser}, localUsers, nil) } +func (u *User) SyncLoginUserInfoWithoutNotice(ctx context.Context) error { + remoteUser, err := u.GetSingleUserFromSvr(ctx, u.loginUserID) + if err != nil { + return err + } + localUser, err := u.GetLoginUser(ctx, u.loginUserID) + if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound { + log.ZError(ctx, "SyncLoginUserInfo", err) + } + var localUsers []*model_struct.LocalUser + if err == nil { + localUsers = []*model_struct.LocalUser{localUser} + } + log.ZDebug(ctx, "SyncLoginUserInfo", "remoteUser", remoteUser, "localUser", localUser) + return u.userSyncer.Sync(ctx, []*model_struct.LocalUser{remoteUser}, localUsers, nil, false, true) +} func (u *User) SyncUserStatus(ctx context.Context, fromUserID string, status int32, platformID int32) { userOnlineStatus := userPb.OnlineStatus{ @@ -95,3 +110,19 @@ func (u *User) SyncAllCommand(ctx context.Context) error { log.ZDebug(ctx, "sync command", "data from server", serverData, "data from local", localData) return u.commandSyncer.Sync(ctx, datautil.Batch(ServerCommandToLocalCommand, serverData.CommandResp), localData, nil) } + +func (u *User) SyncAllCommandWithoutNotice(ctx context.Context) error { + var serverData CommandInfoResponse + err := util.ApiPost(ctx, constant.ProcessUserCommandGetAll, userPb.ProcessUserCommandGetAllReq{ + UserID: u.loginUserID, + }, &serverData) + if err != nil { + return err + } + localData, err := u.DataBase.ProcessUserCommandGetAll(ctx) + if err != nil { + return err + } + log.ZDebug(ctx, "sync command", "data from server", serverData, "data from local", localData) + return u.commandSyncer.Sync(ctx, datautil.Batch(ServerCommandToLocalCommand, serverData.CommandResp), localData, nil, false, true) +} diff --git a/open_im_sdk/em.go b/open_im_sdk/em.go index 9ef80a8fd..e7f0e7f8b 100644 --- a/open_im_sdk/em.go +++ b/open_im_sdk/em.go @@ -142,17 +142,21 @@ func newEmptyConversationListener(ctx context.Context) open_im_sdk_callback.OnCo return &emptyConversationListener{ctx: ctx} } -func (e *emptyConversationListener) OnSyncServerStart() { - +func (e *emptyConversationListener) OnSyncServerStart(reinstalled bool) { log.ZWarn(e.ctx, "ConversationListener is not implemented", nil) } -func (e *emptyConversationListener) OnSyncServerFinish() { +func (e *emptyConversationListener) OnSyncServerProgress(progress int) { + log.ZWarn(e.ctx, "ConversationListener is not implemented", nil, + "progress", progress) +} + +func (e *emptyConversationListener) OnSyncServerFinish(reinstalled bool) { log.ZWarn(e.ctx, "ConversationListener is not implemented", nil) } -func (e *emptyConversationListener) OnSyncServerFailed() { +func (e *emptyConversationListener) OnSyncServerFailed(reinstalled bool) { log.ZWarn(e.ctx, "ConversationListener is not implemented", nil) } diff --git a/open_im_sdk_callback/callback_client.go b/open_im_sdk_callback/callback_client.go index e5643cdad..0a003ce4b 100644 --- a/open_im_sdk_callback/callback_client.go +++ b/open_im_sdk_callback/callback_client.go @@ -57,10 +57,10 @@ type OnFriendshipListener interface { OnBlackDeleted(blackInfo string) } type OnConversationListener interface { - OnSyncServerStart() - OnSyncServerFinish() - //OnSyncServerProgress(progress int) - OnSyncServerFailed() + OnSyncServerStart(reinstalled bool) + OnSyncServerFinish(reinstalled bool) + OnSyncServerProgress(progress int) + OnSyncServerFailed(reinstalled bool) OnNewConversation(conversationList string) OnConversationChanged(conversationList string) OnTotalUnreadMessageCountChanged(totalUnreadCount int32) diff --git a/pkg/common/trigger_channel.go b/pkg/common/trigger_channel.go index cb8d1f9cc..6ca38db53 100644 --- a/pkg/common/trigger_channel.go +++ b/pkg/common/trigger_channel.go @@ -44,22 +44,12 @@ func TriggerCmdNewMsgCome(ctx context.Context, msg sdk_struct.CmdNewMsgComeToCon return sendCmd(conversationCh, c2v, 100) } -func TriggerCmdSuperGroupMsgCome(msg sdk_struct.CmdNewMsgComeToConversation, conversationCh chan Cmd2Value) error { - if conversationCh == nil { - return utils.Wrap(errors.New("ch == nil"), "") - } - - c2v := Cmd2Value{Cmd: constant.CmdSuperGroupMsgCome, Value: msg} - return sendCmd(conversationCh, c2v, 100) -} - -func TriggerCmdNotification(ctx context.Context, msg sdk_struct.CmdNewMsgComeToConversation, conversationCh chan Cmd2Value) error { - if conversationCh == nil { - return utils.Wrap(errors.New("ch == nil"), "") - } - +func TriggerCmdNotification(ctx context.Context, msg sdk_struct.CmdNewMsgComeToConversation, conversationCh chan Cmd2Value) { c2v := Cmd2Value{Cmd: constant.CmdNotification, Value: msg, Ctx: ctx} - return sendCmd(conversationCh, c2v, 100) + err := sendCmd(conversationCh, c2v, 100) + if err != nil { + log.ZWarn(ctx, "TriggerCmdNotification error", err, "msg", msg) + } } func TriggerCmdWakeUp(ch chan Cmd2Value) error { diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go index e46f4809a..aaa9068ce 100644 --- a/pkg/constant/constant.go +++ b/pkg/constant/constant.go @@ -403,6 +403,8 @@ const ( MsgSyncProcessing = 1002 // MsgSyncEnd = 1003 // MsgSyncFailed = 1004 + AppDataSyncStart = 1005 + AppDataSyncFinish = 1006 ) const ( diff --git a/pkg/db/db_interface/databse.go b/pkg/db/db_interface/databse.go index c2b9dd236..3c92407b8 100644 --- a/pkg/db/db_interface/databse.go +++ b/pkg/db/db_interface/databse.go @@ -173,6 +173,7 @@ type MessageModel interface { DeleteConversationMsgs(ctx context.Context, conversationID string, msgIDs []string) error // DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error + BatchInsertNotificationSeq(ctx context.Context, notificationSeqs []*model_struct.NotificationSeqs) error GetNotificationAllSeqs(ctx context.Context) ([]*model_struct.NotificationSeqs, error) } diff --git a/pkg/db/notification_model.go b/pkg/db/notification_model.go index 70fc13853..89a28bd1f 100644 --- a/pkg/db/notification_model.go +++ b/pkg/db/notification_model.go @@ -21,6 +21,7 @@ import ( "context" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/utils" + "github.com/openimsdk/tools/errs" ) func (d *DataBase) SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error { @@ -36,6 +37,12 @@ func (d *DataBase) SetNotificationSeq(ctx context.Context, conversationID string return nil } +func (d *DataBase) BatchInsertNotificationSeq(ctx context.Context, notificationSeqs []*model_struct.NotificationSeqs) error { + d.mRWMutex.Lock() + defer d.mRWMutex.Unlock() + return errs.WrapMsg(d.conn.WithContext(ctx).Create(notificationSeqs).Error, "BatchInsertNotificationSeq failed") +} + func (d *DataBase) GetNotificationAllSeqs(ctx context.Context) ([]*model_struct.NotificationSeqs, error) { d.mRWMutex.Lock() defer d.mRWMutex.Unlock() diff --git a/test/t_conversation_msg.go b/test/t_conversation_msg.go index c0d1373f3..cfcb56c7c 100644 --- a/test/t_conversation_msg.go +++ b/test/t_conversation_msg.go @@ -653,16 +653,16 @@ func (c *conversationCallBack) OnSyncServerProgress(progress int) { log.ZInfo(ctx, utils.GetSelfFuncName(), "progress", progress) } -func (c *conversationCallBack) OnSyncServerStart() { +func (c *conversationCallBack) OnSyncServerStart(reinstalled bool) { } -func (c *conversationCallBack) OnSyncServerFinish() { +func (c *conversationCallBack) OnSyncServerFinish(reinstalled bool) { c.SyncFlag = 1 log.ZInfo(ctx, utils.GetSelfFuncName()) } -func (c *conversationCallBack) OnSyncServerFailed() { +func (c *conversationCallBack) OnSyncServerFailed(reinstalled bool) { log.ZInfo(ctx, utils.GetSelfFuncName()) } From 119ae40efc028ef7ad23645c9251342743248f3d Mon Sep 17 00:00:00 2001 From: Monet Lee Date: Fri, 28 Jun 2024 15:41:04 +0800 Subject: [PATCH 66/69] optimize large sessions blocking in login. --- internal/interaction/msg_sync.go | 53 +++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index 58f9a503b..4f28dec24 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -16,8 +16,11 @@ package interaction import ( "context" - "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "strings" + "sync" + "time" + + "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" "github.com/openimsdk/openim-sdk-core/v3/pkg/common" "github.com/openimsdk/openim-sdk-core/v3/pkg/constant" @@ -78,15 +81,51 @@ func (m *MsgSyncer) loadSeq(ctx context.Context) error { if len(conversationIDList) == 0 { m.reinstalled = true } - //TODO With a large number of sessions, this could potentially cause blocking and needs optimization. + + // TODO With a large number of sessions, this could potentially cause blocking and needs optimization. + type SyncedSeq struct { + ConversationID string + MaxSyncedSeq int64 + Err error + } + concurrency := 10 + t2 := time.Now() + SyncedSeqs := make(chan SyncedSeq, len(conversationIDList)) + sem := make(chan struct{}, concurrency) + + var wg sync.WaitGroup for _, v := range conversationIDList { - maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, v) - if err != nil { - log.ZError(ctx, "get group normal seq failed", err, "conversationID", v) + wg.Add(1) + sem <- struct{}{} // Acquire a token + go func(conversationID string) { + defer wg.Done() + defer func() { <-sem }() // Release the token + + maxSyncedSeq, err := m.db.GetConversationNormalMsgSeq(ctx, conversationID) + SyncedSeqs <- SyncedSeq{ + ConversationID: conversationID, + MaxSyncedSeq: maxSyncedSeq, + Err: err, + } + }(v) + log.ZDebug(ctx, "goroutine done.", "goroutine cost time", time.Since(t2)) + } + + // Close the results channel once all goroutines have finished + go func() { + wg.Wait() + close(SyncedSeqs) + }() + + // Collect the results + for res := range SyncedSeqs { + if res.Err != nil { + log.ZError(ctx, "get group normal seq failed", res.Err, "conversationID", res.ConversationID) } else { - m.syncedMaxSeqs[v] = maxSyncedSeq + m.syncedMaxSeqs[res.ConversationID] = res.MaxSyncedSeq } } + notificationSeqs, err := m.db.GetNotificationAllSeqs(ctx) if err != nil { log.ZError(ctx, "get notification seq failed", err) @@ -246,7 +285,7 @@ func (m *MsgSyncer) doConnected(ctx context.Context) { common.TriggerCmdNotification(m.ctx, sdk_struct.CmdNewMsgComeToConversation{SyncFlag: constant.MsgSyncFailed}, m.conversationCh) return } else { - log.ZDebug(m.ctx, "get max seq success", "resp", resp) + log.ZDebug(m.ctx, "get max seq success", "resp", resp.MaxSeqs) } m.compareSeqsAndBatchSync(ctx, resp.MaxSeqs, connectPullNums) if reinstalled { From f16080c8a37566886b346d9563681c9e5d525f7b Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:13:27 +0800 Subject: [PATCH 67/69] fix: reinstall app sync data split. --- internal/conversation_msg/conversation_notification.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 68f09c848..ea2a13509 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -89,7 +89,7 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } case constant.AppDataSyncFinish: log.ZDebug(ctx, "AppDataSyncFinish", "time", time.Since(c.startTime).Milliseconds()) - c.ConversationListener().OnSyncServerFailed(true) + c.ConversationListener().OnSyncServerFinish(true) case constant.MsgSyncBegin: log.ZDebug(ctx, "MsgSyncBegin") c.startTime = time.Now() From e06a676933541086b00bc336b8f4b093741aaaf9 Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:58:09 +0800 Subject: [PATCH 68/69] fix: reinstall app sync data split. --- internal/conversation_msg/sdk.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/conversation_msg/sdk.go b/internal/conversation_msg/sdk.go index 6a2321d8f..4e6913b22 100644 --- a/internal/conversation_msg/sdk.go +++ b/internal/conversation_msg/sdk.go @@ -331,6 +331,13 @@ func (c *Conversation) checkID(ctx context.Context, s *sdk_struct.MsgStruct, if gm.Nickname != "" { s.SenderNickname = gm.Nickname } + } else { //Maybe the group member information hasn't been pulled locally yet. + gm, err := c.group.GetSpecifiedGroupMembersInfo(ctx, groupID, []string{c.loginUserID}) + if err == nil && gm != nil { + if gm[0].Nickname != "" { + s.SenderNickname = gm[0].Nickname + } + } } var attachedInfo sdk_struct.AttachedInfoElem attachedInfo.GroupHasReadInfo.GroupMemberCount = g.MemberCount From fe7a6d93737ed416c46516f0c3495b3ebaf23d56 Mon Sep 17 00:00:00 2001 From: Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:04:19 +0800 Subject: [PATCH 69/69] docs: update code's comment. --- internal/incrversion/option.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/incrversion/option.go b/internal/incrversion/option.go index 50b43ea4e..9c7024143 100644 --- a/internal/incrversion/option.go +++ b/internal/incrversion/option.go @@ -217,15 +217,15 @@ func (o *VersionSynchronizer[V, R]) CheckVersionSync() error { } } -// DeleteElements 删除切片中包含在另一个切片中的元素,并保持切片顺序 +// DeleteElements removes elements from a slice that are contained in another slice, while maintaining the order of the slice func DeleteElements[E comparable](es []E, toDelete []E) []E { - // 将要删除的元素存储在哈希集合中 + // Store the elements to be deleted in a hash set deleteSet := make(map[E]struct{}, len(toDelete)) for _, e := range toDelete { deleteSet[e] = struct{}{} } - // 通过一个索引 j 来跟踪新的切片位置 + // Use an index j to track the new slice position j := 0 for _, e := range es { if _, found := deleteSet[e]; !found { @@ -236,7 +236,7 @@ func DeleteElements[E comparable](es []E, toDelete []E) []E { return es[:j] } -// DeleteElement 删除切片中的指定元素,并保持切片顺序 +// DeleteElement removes a specified element from a slice while maintaining the order of the slice func DeleteElement[E comparable](es []E, element E) []E { j := 0 for _, e := range es { @@ -248,15 +248,15 @@ func DeleteElement[E comparable](es []E, element E) []E { return es[:j] } -// Slice Converts slice types in batches and sorts the resulting slice using a custom comparator +// Slice converts slice types in batches and sorts the resulting slice using a custom comparator func Slice[E any, T any](es []E, fn func(e E) T, less func(a, b T) bool) []T { - // 转换切片 + // Convert the slice v := make([]T, len(es)) for i := 0; i < len(es); i++ { v[i] = fn(es[i]) } - // 排序切片 + // Sort the slice sort.Slice(v, func(i, j int) bool { return less(v[i], v[j]) })