1 /*
2 * Copyright (c) 2024 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-ExportDbStorage");
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 NativeRdb::ValuesBucket bucket;
92 bucket.PutString(COLUMN_MODULE_NAME, record.moduleName);
93 bucket.PutLong(COLUMN_EXPORT_ENABLED_SEQ, record.exportEnabledSeq);
94 bucket.PutLong(COLUMN_EXPORTED_MAX_SEQ, record.exportedMaxSeq);
95 int64_t id = 0;
96 if (dbStore_->Insert(id, MODULE_EXPORT_DETAILS_TABLE_NAME, bucket) != NativeRdb::E_OK) {
97 HIVIEW_LOGE("failed to insert record into %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
98 }
99 }
100
UpdateExportEnabledSeq(ExportDetailRecord & record)101 void ExportDbStorage::UpdateExportEnabledSeq(ExportDetailRecord& record)
102 {
103 UpdateExportDetailRecordSeq(record, COLUMN_EXPORT_ENABLED_SEQ, record.exportEnabledSeq);
104 }
105
UpdateExportedMaxSeq(ExportDetailRecord & record)106 void ExportDbStorage::UpdateExportedMaxSeq(ExportDetailRecord& record)
107 {
108 UpdateExportDetailRecordSeq(record, COLUMN_EXPORTED_MAX_SEQ, record.exportedMaxSeq);
109 }
110
QueryExportDetailRecord(const std::string & moduleName,ExportDetailRecord & record)111 void ExportDbStorage::QueryExportDetailRecord(const std::string& moduleName, ExportDetailRecord& record)
112 {
113 if (moduleName.empty()) {
114 HIVIEW_LOGW("query record with an empty module name");
115 return;
116 }
117 NativeRdb::RdbPredicates predicates(MODULE_EXPORT_DETAILS_TABLE_NAME);
118 predicates.EqualTo(COLUMN_MODULE_NAME, moduleName);
119 std::vector<std::string> columns;
120 columns.emplace_back(COLUMN_MODULE_NAME);
121 columns.emplace_back(COLUMN_EXPORT_ENABLED_SEQ);
122 columns.emplace_back(COLUMN_EXPORTED_MAX_SEQ);
123 std::shared_ptr<NativeRdb::ResultSet> records = dbStore_->Query(predicates, columns);
124 if (records == nullptr) {
125 HIVIEW_LOGE("records is null");
126 return;
127 }
128 if (records->GoToFirstRow() != NativeRdb::E_OK) {
129 HIVIEW_LOGE("failed to query record from %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
130 records->Close();
131 return;
132 }
133 NativeRdb::RowEntity entity;
134 if (records->GetRow(entity) != NativeRdb::E_OK) {
135 HIVIEW_LOGE("failed to read row entity from result set.");
136 records->Close();
137 return;
138 }
139 if (entity.Get(COLUMN_MODULE_NAME).GetString(record.moduleName) != NativeRdb::E_OK ||
140 entity.Get(COLUMN_EXPORT_ENABLED_SEQ).GetLong(record.exportEnabledSeq) != NativeRdb::E_OK ||
141 entity.Get(COLUMN_EXPORTED_MAX_SEQ).GetLong(record.exportedMaxSeq) != NativeRdb::E_OK) {
142 HIVIEW_LOGE("failed to read module_name/export_enabled_seq/exported_max_seq from entity.");
143 }
144 records->Close();
145 }
146
InitDbStore(const std::string & dbStoreDir)147 void ExportDbStorage::InitDbStore(const std::string& dbStoreDir)
148 {
149 std::string dbStorePath = FileUtil::IncludeTrailingPathDelimiter(dbStoreDir);
150 if (!FileUtil::IsDirectory(dbStorePath) && !FileUtil::ForceCreateDirectory(dbStorePath)) {
151 HIVIEW_LOGE("failed to create dir=%{public}s.", dbStorePath.c_str());
152 return;
153 }
154 dbStorePath.append(EXPORT_DB_NAME);
155 HIVIEW_LOGD("db store path=%{public}s.", dbStorePath.c_str());
156 NativeRdb::RdbStoreConfig config(dbStorePath);
157 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
158 ExportDbOpenCallback callback;
159 auto ret = NativeRdb::E_OK;
160 dbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
161 if (ret != NativeRdb::E_OK) {
162 HIVIEW_LOGE("failed to init db store, db store path=%{public}s.", dbStorePath.c_str());
163 dbStore_ = nullptr;
164 return;
165 }
166 }
167
UpdateExportDetailRecordSeq(ExportDetailRecord & record,const std::string & seqName,int64_t seqValue)168 void ExportDbStorage::UpdateExportDetailRecordSeq(ExportDetailRecord& record, const std::string& seqName,
169 int64_t seqValue)
170 {
171 NativeRdb::ValuesBucket bucket;
172 bucket.PutLong(seqName, seqValue);
173 int changeRow = 0;
174 std::string condition(COLUMN_MODULE_NAME);
175 condition.append(" = ?");
176 if (dbStore_->Update(changeRow, MODULE_EXPORT_DETAILS_TABLE_NAME, bucket,
177 condition, std::vector<std::string> { record.moduleName }) != NativeRdb::E_OK) {
178 HIVIEW_LOGE("failed to update record in %{public}s table.", MODULE_EXPORT_DETAILS_TABLE_NAME);
179 }
180 }
181 } // HiviewDFX
182 } // OHOS