• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "KnowledgeSchemaHelper"
16 #include "knowledge_schema_helper.h"
17 
18 #ifndef CROSS_PLATFORM
19 #include <dlfcn.h>
20 #endif
21 #include <fstream>
22 #include <sstream>
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_fault_hiview_reporter.h"
26 #include "sqlite_utils.h"
27 #include "task_executor.h"
28 
29 namespace OHOS::NativeRdb {
30 using namespace OHOS::Rdb;
31 
32 static constexpr int AIP_MODULE_ID = 13;
33 constexpr ErrCode AIP_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, AIP_MODULE_ID);
34 constexpr int32_t KNOWLEDGE_BASE_ERROR_CODE_OFFSET{ 20000 };
35 constexpr ErrCode KNOWLEDGE_BASE_FAIL = AIP_ERR_OFFSET + KNOWLEDGE_BASE_ERROR_CODE_OFFSET;
36 constexpr ErrCode KNOWLEDGE_SCHEMA_NOT_VALID = KNOWLEDGE_BASE_FAIL + 1;
37 
~KnowledgeSchemaHelper()38 KnowledgeSchemaHelper::~KnowledgeSchemaHelper()
39 {
40     std::unique_lock<std::shared_mutex> writeLock(libMutex_);
41     if (schemaManager_ != nullptr) {
42         schemaManager_->StopTask(dbName_);
43         delete schemaManager_;
44         schemaManager_ = nullptr;
45     }
46 #ifndef CROSS_PLATFORM
47     if (dlHandle_ != nullptr) {
48         dlclose(dlHandle_);
49         dlHandle_ = nullptr;
50     }
51 #endif
52 }
53 
Init(const RdbStoreConfig & config,const DistributedRdb::RdbKnowledgeSchema & schema)54 void KnowledgeSchemaHelper::Init(const RdbStoreConfig &config, const DistributedRdb::RdbKnowledgeSchema &schema)
55 {
56     LoadKnowledgeLib();
57     if (!IsLoadLib()) {
58         LOG_WARN("skip init by miss lib");
59         return;
60     }
61     std::unique_lock<std::shared_mutex> writeLock(libMutex_);
62     if (schemaManager_ == nullptr) {
63         LOG_WARN("skip init by miss manager");
64         return;
65     }
66     schemaManager_->Init(config, schema);
67     bundleName_ = config.GetBundleName();
68     dbName_ = config.GetName();
69     inited_ = true;
70 }
71 
GetRdbKnowledgeSchema(const std::string & dbName)72 std::pair<int, DistributedRdb::RdbKnowledgeSchema> KnowledgeSchemaHelper::GetRdbKnowledgeSchema(
73     const std::string &dbName)
74 {
75     std::pair<int, DistributedRdb::RdbKnowledgeSchema> res;
76     auto &[errCode, schema] = res;
77     LoadKnowledgeLib();
78     if (!IsLoadLib()) {
79         LOG_WARN("skip get donate data by miss lib");
80         errCode = E_ERROR;
81         return res;
82     }
83     std::shared_lock<std::shared_mutex> readLock(libMutex_);
84     if (schemaManager_ == nullptr) {
85         LOG_WARN("skip get donate data by miss manager");
86         errCode = E_ERROR;
87         return res;
88     }
89     errCode = E_OK;
90     auto kSchema = schemaManager_->GetRdbKnowledgeSchema(dbName);
91     if (kSchema == nullptr) {
92         LOG_WARN("unable to get knowledge schema.");
93         RdbFaultHiViewReporter::ReportRAGFault("Parse knowledge schema failed", "ParseRdbKnowledgeSchema", bundleName_,
94             KNOWLEDGE_BASE_FAIL, KNOWLEDGE_SCHEMA_NOT_VALID);
95         errCode = E_ERROR;
96         return res;
97     }
98     schema = *kSchema;
99     return res;
100 }
101 
DonateKnowledgeData()102 void KnowledgeSchemaHelper::DonateKnowledgeData()
103 {
104     if (!inited_) {
105         LOG_WARN("knowledge schema helper not init.");
106         return;
107     }
108     LoadKnowledgeLib();
109     if (!IsLoadLib()) {
110         LOG_WARN("skip donate data by miss lib");
111         return;
112     }
113     auto executor = TaskExecutor::GetInstance().GetExecutor();
114     if (executor == nullptr) {
115         LOG_WARN("skip donate data by miss pool");
116         return;
117     }
118     std::shared_lock<std::shared_mutex> readLock(libMutex_);
119     if (schemaManager_ == nullptr) {
120         LOG_WARN("skip donate data by miss manager");
121         return;
122     }
123     std::weak_ptr<KnowledgeSchemaHelper> helper = shared_from_this();
124     executor->Execute([helper]() {
125         auto realHelper = helper.lock();
126         if (realHelper == nullptr) {
127             LOG_WARN("knowledge helper is null");
128             return;
129         }
130         realHelper->StartTask();
131     });
132 }
133 
LoadKnowledgeLib()134 void KnowledgeSchemaHelper::LoadKnowledgeLib()
135 {
136 #ifndef CROSS_PLATFORM
137     std::unique_lock<std::shared_mutex> writeLock(libMutex_);
138     if (dlHandle_ != nullptr) {
139         return;
140     }
141     auto handle = dlopen("libaip_knowledge_process.z.so", RTLD_LAZY);
142     if (handle != nullptr) {
143         LoadKnowledgeSchemaManager(handle);
144         dlHandle_ = handle;
145     } else {
146         LOG_WARN("unable to load lib, errno: %{public}d, %{public}s", errno, dlerror());
147     }
148 #endif
149 }
150 
LoadKnowledgeSchemaManager(void * handle)151 void KnowledgeSchemaHelper::LoadKnowledgeSchemaManager(void *handle)
152 {
153 #ifndef CROSS_PLATFORM
154     typedef DistributedRdb::IKnowledgeSchemaManager* (*CreateKnowledgeSchemaManager)();
155     auto creator = (CreateKnowledgeSchemaManager)(dlsym(handle, "CreateKnowledgeSchemaManager"));
156     if (creator == nullptr) {
157         LOG_WARN("unable to load creator, errno: %{public}d, %{public}s", errno, dlerror());
158         return;
159     }
160     schemaManager_ = creator();
161     if (schemaManager_ != nullptr) {
162         LOG_INFO("load creator success");
163     } else {
164         LOG_WARN("load creator failed with oom");
165     }
166 #endif
167 }
168 
IsLoadLib() const169 bool KnowledgeSchemaHelper::IsLoadLib() const
170 {
171 #ifndef CROSS_PLATFORM
172     std::shared_lock<std::shared_mutex> readLock(libMutex_);
173     return dlHandle_ != nullptr;
174 #else
175     return false;
176 #endif
177 }
178 
StartTask()179 void KnowledgeSchemaHelper::StartTask()
180 {
181     DistributedRdb::IKnowledgeSchemaManager *manager = nullptr;
182     {
183         std::shared_lock<std::shared_mutex> readLock(libMutex_);
184         if (schemaManager_ == nullptr) {
185             LOG_WARN("skip execute donate data by miss manager");
186             return;
187         }
188         manager = schemaManager_;
189     }
190     manager->StartTask(dbName_);
191 }
192 
Close()193 void KnowledgeSchemaHelper::Close()
194 {
195     std::unique_lock<std::shared_mutex> writeLock(libMutex_);
196     if (schemaManager_ != nullptr) {
197         schemaManager_->StopTask(dbName_);
198     }
199 }
200 }