1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define LOG_TAG "RdbSqlLog"
17
18 #include "rdb_sql_log.h"
19
20 #include "concurrent_map.h"
21 #include "logger.h"
22 #include "rdb_errno.h"
23 #include "rdb_platform.h"
24 #include "task_executor.h"
25
26 namespace OHOS::NativeRdb {
27 ConcurrentMap<std::string, std::set<std::shared_ptr<SqlErrorObserver>>> SqlLog::observerSets_;
28 std::atomic<bool> SqlLog::enabled_ = false;
29 std::shared_mutex SqlLog::mutex_;
30 std::map<uint64_t, int32_t> SqlLog::suspenders_;
Subscribe(const std::string storeId,std::shared_ptr<SqlErrorObserver> observer)31 int SqlLog::Subscribe(const std::string storeId, std::shared_ptr<SqlErrorObserver> observer)
32 {
33 observerSets_.Compute(storeId, [observer](const std::string& key, auto& observers) {
34 observers.insert(observer);
35 enabled_ = true;
36 return true;
37 });
38 return E_OK;
39 }
40
Unsubscribe(const std::string storeId,std::shared_ptr<SqlErrorObserver> observer)41 int SqlLog::Unsubscribe(const std::string storeId, std::shared_ptr<SqlErrorObserver> observer)
42 {
43 observerSets_.ComputeIfPresent(storeId,
44 [observer](const std::string& key, std::set<std::shared_ptr<SqlErrorObserver>>& observers) {
45 observers.erase(observer);
46 return observer !=nullptr && !observers.empty();
47 });
48 observerSets_.DoActionIfEmpty([]() {
49 enabled_ = false;
50 });
51 return E_OK;
52 }
53
Notify(const std::string & storeId,const ExceptionMessage & exceptionMessage)54 void SqlLog::Notify(const std::string &storeId, const ExceptionMessage &exceptionMessage)
55 {
56 if (!enabled_ || IsPause()) {
57 return;
58 }
59 if (!observerSets_.Contains(storeId)) {
60 return;
61 }
62 auto executor = TaskExecutor::GetInstance().GetExecutor();
63 if (executor == nullptr) {
64 return;
65 }
66 executor->Execute([exceptionMessage, storeId]() {
67 auto it = observerSets_.Find(storeId);
68 if (!it.first) {
69 return;
70 }
71 for (const auto &observer: it.second) {
72 if (observer) {
73 observer->OnErrorLog(exceptionMessage);
74 }
75 }
76 });
77 }
78
Pause()79 void SqlLog::Pause()
80 {
81 std::unique_lock<decltype(mutex_)> lock(mutex_);
82 suspenders_[GetThreadId()] = std::max(1, ++suspenders_[GetThreadId()]);
83 }
84
Resume()85 void SqlLog::Resume()
86 {
87 std::unique_lock<decltype(mutex_)> lock(mutex_);
88 suspenders_[GetThreadId()] = std::max(0, --suspenders_[GetThreadId()]);
89 }
90
IsPause()91 bool SqlLog::IsPause()
92 {
93 std::shared_lock<decltype(mutex_)> lock(mutex_);
94 auto it = suspenders_.find(GetThreadId());
95 return it != suspenders_.end() && it->second > 0;
96 }
97
SqlLog()98 SqlLog::SqlLog()
99 {
100 }
101
~SqlLog()102 SqlLog::~SqlLog()
103 {
104 }
105
106 }