• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 #include "export_db_storage.h"
17 
18 #include "file_util.h"
19 #include "hiview_logger.h"
20 #include "rdb_predicates.h"
21 #include "sql_util.h"
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 DEFINE_LOG_TAG("HiView-EventExportDb");
26 namespace {
27 constexpr int32_t DB_VERSION = 1;
28 constexpr char EXPORT_DB_NAME[] = "event_export_mgr.db";
29 constexpr char MODULE_EXPORT_DETAILS_TABLE_NAME[] = "module_export_details";
30 constexpr char COLUMN_ID[] = "id";
31 constexpr char COLUMN_MODULE_NAME[] = "module_name";
32 constexpr char COLUMN_EXPORT_ENABLED_SEQ[] = "export_enabled_seq";
33 constexpr char COLUMN_EXPORTED_MAX_SEQ[] = "exported_max_seq";
34 
CreateTable(NativeRdb::RdbStore & dbStore,const std::string & tableName,const std::vector<std::pair<std::string,std::string>> & fields)35 int32_t CreateTable(NativeRdb::RdbStore& dbStore, const std::string& tableName,
36     const std::vector<std::pair<std::string, std::string>>& fields)
37 {
38     std::string sql = SqlUtil::GenerateCreateSql(tableName, fields);
39     auto ret = dbStore.ExecuteSql(sql);
40     if (ret != NativeRdb::E_OK) {
41         HIVIEW_LOGE("failed to execute sql=%{public}s.", sql.c_str());
42     }
43     return ret;
44 }
45 
CreateExportDetailsTable(NativeRdb::RdbStore & dbStore)46 int32_t CreateExportDetailsTable(NativeRdb::RdbStore& dbStore)
47 {
48     /**
49      * table: module_export_details
50      *
51      * |-----|-------------|--------------------|---------------------|
52      * |  id | module_name | export_enabled_seq |  exported_max_seq   |
53      * |-----|-------------|--------------------|---------------------|
54      * | INT |   VARCHAR   |      INTEGER       |       INTEGER       |
55      * |-----|-------------|--------------------|---------------------|
56      */
57     const std::vector<std::pair<std::string, std::string>> fields = {
58         {COLUMN_MODULE_NAME, SqlUtil::COLUMN_TYPE_STR},
59         {COLUMN_EXPORT_ENABLED_SEQ, SqlUtil::COLUMN_TYPE_INT},
60         {COLUMN_EXPORTED_MAX_SEQ, SqlUtil::COLUMN_TYPE_INT},
61     };
62     if (auto ret = CreateTable(dbStore, MODULE_EXPORT_DETAILS_TABLE_NAME, fields); ret != NativeRdb::E_OK) {
63         HIVIEW_LOGE("failed to create %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
64         return ret;
65     }
66     return NativeRdb::E_OK;
67 }
68 }
69 
OnCreate(NativeRdb::RdbStore & rdbStore)70 int ExportDbOpenCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
71 {
72     if (auto ret = CreateExportDetailsTable(rdbStore); ret != NativeRdb::E_OK) {
73         return ret;
74     }
75     return NativeRdb::E_OK;
76 }
77 
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)78 int ExportDbOpenCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion)
79 {
80     HIVIEW_LOGD("oldVersion=%{public}d, newVersion=%{public}d.", oldVersion, newVersion);
81     return NativeRdb::E_OK;
82 }
83 
ExportDbStorage(const std::string & dbStoreDir)84 ExportDbStorage::ExportDbStorage(const std::string& dbStoreDir)
85 {
86     InitDbStore(dbStoreDir);
87 }
88 
InsertExportDetailRecord(ExportDetailRecord & record)89 void ExportDbStorage::InsertExportDetailRecord(ExportDetailRecord& record)
90 {
91     if (dbStore_ == nullptr) {
92         HIVIEW_LOGE("dbStore_ is null");
93         return;
94     }
95     NativeRdb::ValuesBucket bucket;
96     bucket.PutString(COLUMN_MODULE_NAME, record.moduleName);
97     bucket.PutLong(COLUMN_EXPORT_ENABLED_SEQ, record.exportEnabledSeq);
98     bucket.PutLong(COLUMN_EXPORTED_MAX_SEQ, record.exportedMaxSeq);
99     int64_t id = 0;
100     if (dbStore_->Insert(id, MODULE_EXPORT_DETAILS_TABLE_NAME, bucket) != NativeRdb::E_OK) {
101         HIVIEW_LOGE("failed to insert record into %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
102     }
103 }
104 
UpdateExportEnabledSeq(ExportDetailRecord & record)105 void ExportDbStorage::UpdateExportEnabledSeq(ExportDetailRecord& record)
106 {
107     UpdateExportDetailRecordSeq(record, COLUMN_EXPORT_ENABLED_SEQ, record.exportEnabledSeq);
108 }
109 
UpdateExportedMaxSeq(ExportDetailRecord & record)110 void ExportDbStorage::UpdateExportedMaxSeq(ExportDetailRecord& record)
111 {
112     UpdateExportDetailRecordSeq(record, COLUMN_EXPORTED_MAX_SEQ, record.exportedMaxSeq);
113 }
114 
QueryExportDetailRecord(const std::string & moduleName,ExportDetailRecord & record)115 void ExportDbStorage::QueryExportDetailRecord(const std::string& moduleName, ExportDetailRecord& record)
116 {
117     if (dbStore_ == nullptr) {
118         HIVIEW_LOGE("dbStore_ is null");
119         return;
120     }
121     if (moduleName.empty()) {
122         HIVIEW_LOGW("query record with an empty module name");
123         return;
124     }
125     NativeRdb::RdbPredicates predicates(MODULE_EXPORT_DETAILS_TABLE_NAME);
126     predicates.EqualTo(COLUMN_MODULE_NAME, moduleName);
127     std::vector<std::string> columns;
128     columns.emplace_back(COLUMN_MODULE_NAME);
129     columns.emplace_back(COLUMN_EXPORT_ENABLED_SEQ);
130     columns.emplace_back(COLUMN_EXPORTED_MAX_SEQ);
131     std::shared_ptr<NativeRdb::ResultSet> records = dbStore_->Query(predicates, columns);
132     if (records == nullptr) {
133         HIVIEW_LOGE("records is null");
134         return;
135     }
136     if (records->GoToFirstRow() != NativeRdb::E_OK) {
137         HIVIEW_LOGW("no record with name %{public}s found.", moduleName.c_str());
138         records->Close();
139         return;
140     }
141     NativeRdb::RowEntity entity;
142     if (records->GetRow(entity) != NativeRdb::E_OK) {
143         HIVIEW_LOGE("failed to read row entity from result set.");
144         records->Close();
145         return;
146     }
147     if (entity.Get(COLUMN_MODULE_NAME).GetString(record.moduleName) != NativeRdb::E_OK ||
148         entity.Get(COLUMN_EXPORT_ENABLED_SEQ).GetLong(record.exportEnabledSeq) != NativeRdb::E_OK ||
149         entity.Get(COLUMN_EXPORTED_MAX_SEQ).GetLong(record.exportedMaxSeq) != NativeRdb::E_OK) {
150         HIVIEW_LOGE("failed to read module_name/export_enabled_seq/exported_max_seq from entity.");
151     }
152     records->Close();
153 }
154 
InitDbStore(const std::string & dbStoreDir)155 void ExportDbStorage::InitDbStore(const std::string& dbStoreDir)
156 {
157     std::string dbStorePath = FileUtil::IncludeTrailingPathDelimiter(dbStoreDir);
158     if (!FileUtil::IsDirectory(dbStorePath) && !FileUtil::ForceCreateDirectory(dbStorePath)) {
159         HIVIEW_LOGE("failed to create dir=%{public}s.", dbStorePath.c_str());
160         return;
161     }
162     dbStorePath.append(EXPORT_DB_NAME);
163     HIVIEW_LOGD("db store path=%{public}s.", dbStorePath.c_str());
164     NativeRdb::RdbStoreConfig config(dbStorePath);
165     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
166     ExportDbOpenCallback callback;
167     auto ret = NativeRdb::E_OK;
168     dbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
169     if (ret != NativeRdb::E_OK) {
170         HIVIEW_LOGE("failed to init db store, db store path=%{public}s.", dbStorePath.c_str());
171         dbStore_ = nullptr;
172         return;
173     }
174 }
175 
UpdateExportDetailRecordSeq(ExportDetailRecord & record,const std::string & seqName,int64_t seqValue)176 void ExportDbStorage::UpdateExportDetailRecordSeq(ExportDetailRecord& record, const std::string& seqName,
177     int64_t seqValue)
178 {
179     if (dbStore_ == nullptr) {
180         HIVIEW_LOGE("dbStore_ is null");
181         return;
182     }
183     NativeRdb::ValuesBucket bucket;
184     bucket.PutLong(seqName, seqValue);
185     int changeRow = 0;
186     std::string condition(COLUMN_MODULE_NAME);
187     condition.append(" = ?");
188     if (dbStore_->Update(changeRow, MODULE_EXPORT_DETAILS_TABLE_NAME, bucket,
189         condition, std::vector<std::string> { record.moduleName }) != NativeRdb::E_OK) {
190         HIVIEW_LOGE("failed to update record in %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
191     }
192 }
193 } // HiviewDFX
194 } // OHOS