1 /*
2 * Copyright (c) 2021 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 "SqliteUtils"
16 #include "sqlite_utils.h"
17
18 #include <fcntl.h>
19 #include <sys/file.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23
24 #include <algorithm>
25 #include <cerrno>
26 #include <climits>
27 #include <cstddef>
28 #include <cstdio>
29 #include <cstring>
30 #include <fstream>
31 #include <regex>
32 #include <string>
33 #include <sstream>
34 #include <iomanip>
35
36 #include "logger.h"
37 #include "rdb_errno.h"
38 #include "rdb_store_config.h"
39 #include "string_utils.h"
40 #include "rdb_time_utils.h"
41
42 namespace OHOS {
43 namespace NativeRdb {
44 using namespace OHOS::Rdb;
45
46 /* A continuous number must contain at least eight digits, because the employee ID has eight digits,
47 and the mobile phone number has 11 digits. The UUID is longer */
48 constexpr int32_t CONTINUOUS_DIGITS_MINI_SIZE = 6;
49 constexpr int32_t FILE_PATH_MINI_SIZE = 6;
50 constexpr int32_t AREA_MINI_SIZE = 4;
51 constexpr int32_t AREA_OFFSET_SIZE = 5;
52 constexpr int32_t PRE_OFFSET_SIZE = 1;
53 constexpr int32_t DISPLAY_BYTE = 2;
54 constexpr int32_t PREFIX_LENGTH = 3;
55 constexpr int32_t FILE_MAX_SIZE = 20 * 1024;
56
57 constexpr SqliteUtils::SqlType SqliteUtils::SQL_TYPE_MAP[];
58 constexpr const char *SqliteUtils::ON_CONFLICT_CLAUSE[];
59
GetSqlStatementType(const std::string & sql)60 int SqliteUtils::GetSqlStatementType(const std::string &sql)
61 {
62 /* the sql string length less than 3 can not be any type sql */
63 auto alnum = std::find_if(sql.begin(), sql.end(), [](int ch) { return !std::isspace(ch) && !std::iscntrl(ch); });
64 if (alnum == sql.end()) {
65 return STATEMENT_ERROR;
66 }
67 auto pos = static_cast<std::string::size_type>(alnum - sql.begin());
68 /* 3 represents the number of prefix characters that need to be extracted and checked */
69 if (pos + 3 >= sql.length()) {
70 return STATEMENT_ERROR;
71 }
72 /* analyze the sql type through first 3 characters */
73 std::string prefixSql = StrToUpper(sql.substr(pos, 3));
74 SqlType type = { prefixSql.c_str(), STATEMENT_OTHER };
75 auto comp = [](const SqlType &first, const SqlType &second) {
76 return strcmp(first.sql, second.sql) < 0;
77 };
78 auto it = std::lower_bound(SQL_TYPE_MAP, SQL_TYPE_MAP + TYPE_SIZE, type, comp);
79 if (it < SQL_TYPE_MAP + TYPE_SIZE && !comp(type, *it)) {
80 return it->type;
81 }
82 return STATEMENT_OTHER;
83 }
84
StrToUpper(const std::string & s)85 std::string SqliteUtils::StrToUpper(const std::string &s)
86 {
87 std::string str = s;
88 std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::toupper(c); });
89 return str;
90 }
91
Replace(std::string & src,const std::string & rep,const std::string & dst)92 void SqliteUtils::Replace(std::string &src, const std::string &rep, const std::string &dst)
93 {
94 if (src.empty() || rep.empty()) {
95 return;
96 }
97 size_t pos = 0;
98 while ((pos = src.find(rep, pos)) != std::string::npos) {
99 src.replace(pos, rep.length(), dst);
100 pos += dst.length();
101 }
102 }
103
IsSupportSqlForExecute(int sqlType)104 bool SqliteUtils::IsSupportSqlForExecute(int sqlType)
105 {
106 return (sqlType == STATEMENT_DDL || sqlType == STATEMENT_INSERT || sqlType == STATEMENT_UPDATE ||
107 sqlType == STATEMENT_PRAGMA);
108 }
109
IsSqlReadOnly(int sqlType)110 bool SqliteUtils::IsSqlReadOnly(int sqlType)
111 {
112 return (sqlType == STATEMENT_SELECT);
113 }
114
IsSpecial(int sqlType)115 bool SqliteUtils::IsSpecial(int sqlType)
116 {
117 if (sqlType == STATEMENT_BEGIN || sqlType == STATEMENT_COMMIT || sqlType == STATEMENT_ROLLBACK) {
118 return true;
119 }
120 return false;
121 }
122
GetConflictClause(int conflictResolution)123 const char *SqliteUtils::GetConflictClause(int conflictResolution)
124 {
125 if (conflictResolution < 0 || conflictResolution >= CONFLICT_CLAUSE_COUNT) {
126 return nullptr;
127 }
128 return ON_CONFLICT_CLAUSE[conflictResolution];
129 }
130
DeleteFile(const std::string & filePath)131 bool SqliteUtils::DeleteFile(const std::string &filePath)
132 {
133 if (access(filePath.c_str(), F_OK) != 0) {
134 return true;
135 }
136 auto ret = remove(filePath.c_str());
137 if (ret != 0) {
138 LOG_WARN(
139 "remove file failed errno %{public}d ret %{public}d %{public}s", errno, ret, Anonymous(filePath).c_str());
140 return false;
141 }
142 return true;
143 }
144
RenameFile(const std::string & srcFile,const std::string & destFile)145 bool SqliteUtils::RenameFile(const std::string &srcFile, const std::string &destFile)
146 {
147 auto ret = rename(srcFile.c_str(), destFile.c_str());
148 if (ret != 0) {
149 LOG_WARN("rename failed errno %{public}d ret %{public}d %{public}s -> %{public}s", errno, ret,
150 SqliteUtils::Anonymous(destFile).c_str(), SqliteUtils::Anonymous(srcFile).c_str());
151 return false;
152 }
153 return true;
154 }
155
CopyFile(const std::string & srcFile,const std::string & destFile)156 bool SqliteUtils::CopyFile(const std::string &srcFile, const std::string &destFile)
157 {
158 std::ifstream src(srcFile.c_str(), std::ios::binary);
159 if (!src.is_open()) {
160 LOG_WARN("open srcFile failed errno %{public}d %{public}s", errno, SqliteUtils::Anonymous(srcFile).c_str());
161 return false;
162 }
163 std::ofstream dst(destFile.c_str(), std::ios::binary);
164 if (!dst.is_open()) {
165 src.close();
166 LOG_WARN("open destFile failed errno %{public}d %{public}s", errno, SqliteUtils::Anonymous(destFile).c_str());
167 return false;
168 }
169 dst << src.rdbuf();
170 src.close();
171 dst.close();
172 return true;
173 }
174
GetAnonymousName(const std::string & fileName)175 std::string SqliteUtils::GetAnonymousName(const std::string &fileName)
176 {
177 std::vector<std::string> alnum;
178 std::vector<std::string> noAlnum;
179 std::string alnumStr;
180 std::string noAlnumStr;
181 for (const auto &letter : fileName) {
182 if (isxdigit(letter)) {
183 if (!noAlnumStr.empty()) {
184 noAlnum.push_back(noAlnumStr);
185 noAlnumStr.clear();
186 alnum.push_back("");
187 }
188 alnumStr += letter;
189 } else {
190 if (!alnumStr.empty()) {
191 alnum.push_back(alnumStr);
192 alnumStr.clear();
193 noAlnum.push_back("");
194 }
195 noAlnumStr += letter;
196 }
197 }
198 if (!alnumStr.empty()) {
199 alnum.push_back(alnumStr);
200 noAlnum.push_back("");
201 }
202 if (!noAlnumStr.empty()) {
203 noAlnum.push_back(noAlnumStr);
204 alnum.push_back("");
205 }
206 std::string res = "";
207 for (size_t i = 0; i < alnum.size(); ++i) {
208 res += (AnonyDigits(alnum[i]) + noAlnum[i]);
209 }
210 return res;
211 }
212
AnonyDigits(const std::string & fileName)213 std::string SqliteUtils::AnonyDigits(const std::string &fileName)
214 {
215 std::string::size_type digitsNum = fileName.size();
216 if (digitsNum < CONTINUOUS_DIGITS_MINI_SIZE) {
217 return fileName;
218 }
219 std::string::size_type endDigitsNum = 4;
220 std::string::size_type shortEndDigitsNum = 3;
221 std::string name = fileName;
222 std::string last = "";
223 if (digitsNum == CONTINUOUS_DIGITS_MINI_SIZE) {
224 last = name.substr(name.size() - shortEndDigitsNum);
225 } else {
226 last = name.substr(name.size() - endDigitsNum);
227 }
228 return "***" + last;
229 }
230
Anonymous(const std::string & srcFile)231 std::string SqliteUtils::Anonymous(const std::string &srcFile)
232 {
233 auto pre = srcFile.find("/");
234 auto end = srcFile.rfind("/");
235 if (pre == std::string::npos || end - pre < FILE_PATH_MINI_SIZE) {
236 return GetAnonymousName(srcFile);
237 }
238 auto path = srcFile.substr(pre, end - pre);
239 auto area = path.find("/el");
240 if (area == std::string::npos || area + AREA_MINI_SIZE > path.size()) {
241 path = "";
242 } else if (area + AREA_OFFSET_SIZE < path.size()) {
243 path = path.substr(area, AREA_MINI_SIZE) + "/***";
244 } else {
245 path = path.substr(area, AREA_MINI_SIZE);
246 }
247 std::string fileName = srcFile.substr(end); // rdb file name
248 fileName = GetAnonymousName(fileName);
249 return srcFile.substr(0, pre + PRE_OFFSET_SIZE) + "***" + path + fileName;
250 }
251
GetFileSize(const std::string & fileName)252 ssize_t SqliteUtils::GetFileSize(const std::string &fileName)
253 {
254 struct stat fileStat;
255 if (fileName.empty() || stat(fileName.c_str(), &fileStat) < 0) {
256 if (errno != ENOENT) {
257 LOG_ERROR("failed, errno: %{public}d, fileName:%{public}s", errno, Anonymous(fileName).c_str());
258 }
259 return 0;
260 }
261
262 return fileStat.st_size;
263 }
264
IsSlaveDbName(const std::string & fileName)265 bool SqliteUtils::IsSlaveDbName(const std::string &fileName)
266 {
267 std::string slaveSuffix("_slave.db");
268 if (fileName.size() < slaveSuffix.size()) {
269 return false;
270 }
271 size_t pos = fileName.rfind(slaveSuffix);
272 return (pos != std::string::npos) && (pos == fileName.size() - slaveSuffix.size());
273 }
274
GetSlavePath(const std::string & name)275 std::string SqliteUtils::GetSlavePath(const std::string &name)
276 {
277 std::string suffix(".db");
278 std::string slaveSuffix("_slave.db");
279 auto pos = name.rfind(suffix);
280 if (pos == std::string::npos || pos < name.length() - suffix.length()) {
281 return name + slaveSuffix;
282 }
283 return name.substr(0, pos) + slaveSuffix;
284 }
285
HmacAlgoDescription(int32_t hmacAlgo)286 const char *SqliteUtils::HmacAlgoDescription(int32_t hmacAlgo)
287 {
288 HmacAlgo hmacEnum = static_cast<HmacAlgo>(hmacAlgo);
289 switch (hmacEnum) {
290 case HmacAlgo::SHA1:
291 return "sha1";
292 case HmacAlgo::SHA256:
293 return "sha256";
294 case HmacAlgo::SHA512:
295 return "sha512";
296 default:
297 return "sha256";
298 }
299 }
300
KdfAlgoDescription(int32_t kdfAlgo)301 const char *SqliteUtils::KdfAlgoDescription(int32_t kdfAlgo)
302 {
303 KdfAlgo kdfEnum = static_cast<KdfAlgo>(kdfAlgo);
304 switch (kdfEnum) {
305 case KdfAlgo::KDF_SHA1:
306 return "kdf_sha1";
307 case KdfAlgo::KDF_SHA256:
308 return "kdf_sha256";
309 case KdfAlgo::KDF_SHA512:
310 return "kdf_sha512";
311 default:
312 return "kdf_sha256";
313 }
314 }
315
EncryptAlgoDescription(int32_t encryptAlgo)316 const char *SqliteUtils::EncryptAlgoDescription(int32_t encryptAlgo)
317 {
318 EncryptAlgo encryptEnum = static_cast<EncryptAlgo>(encryptAlgo);
319 switch (encryptEnum) {
320 case EncryptAlgo::AES_256_CBC:
321 return "aes-256-cbc";
322 case EncryptAlgo::AES_256_GCM:
323 default:
324 return "aes-256-gcm";
325 }
326 }
327
SetSlaveInvalid(const std::string & dbPath)328 int SqliteUtils::SetSlaveInvalid(const std::string &dbPath)
329 {
330 if (IsSlaveInvalid(dbPath)) {
331 return E_OK;
332 }
333 std::ofstream src((dbPath + SLAVE_FAILURE).c_str(), std::ios::binary);
334 if (src.is_open()) {
335 src.close();
336 return E_OK;
337 }
338 return E_ERROR;
339 }
340
SetSlaveInterrupted(const std::string & dbPath)341 int SqliteUtils::SetSlaveInterrupted(const std::string &dbPath)
342 {
343 if (IsSlaveInterrupted(dbPath)) {
344 return E_OK;
345 }
346 std::ofstream src((dbPath + SLAVE_INTERRUPT).c_str(), std::ios::binary);
347 if (src.is_open()) {
348 src.close();
349 return E_OK;
350 }
351 return E_ERROR;
352 }
353
IsSlaveInvalid(const std::string & dbPath)354 bool SqliteUtils::IsSlaveInvalid(const std::string &dbPath)
355 {
356 return access((dbPath + SLAVE_FAILURE).c_str(), F_OK) == 0;
357 }
358
IsSlaveInterrupted(const std::string & dbPath)359 bool SqliteUtils::IsSlaveInterrupted(const std::string &dbPath)
360 {
361 return access((dbPath + SLAVE_INTERRUPT).c_str(), F_OK) == 0;
362 }
363
SetSlaveValid(const std::string & dbPath)364 void SqliteUtils::SetSlaveValid(const std::string &dbPath)
365 {
366 std::remove((dbPath + SLAVE_INTERRUPT).c_str());
367 std::remove((dbPath + SLAVE_FAILURE).c_str());
368 }
369
DeleteDirtyFiles(const std::string & backupFilePath)370 bool SqliteUtils::DeleteDirtyFiles(const std::string &backupFilePath)
371 {
372 auto res = DeleteFile(backupFilePath);
373 res = DeleteFile(backupFilePath + "-shm") && res;
374 res = DeleteFile(backupFilePath + "-wal") && res;
375 return res;
376 }
377
Stat(const std::string & path)378 std::pair<int32_t, DistributedRdb::RdbDebugInfo> SqliteUtils::Stat(const std::string &path)
379 {
380 DistributedRdb::RdbDebugInfo info;
381 struct stat fileStat;
382 if (stat(path.c_str(), &fileStat) != 0) {
383 return std::pair{ E_ERROR, info };
384 }
385 info.inode_ = fileStat.st_ino;
386 info.oldInode_ = 0;
387 info.atime_.sec_ = fileStat.st_atime;
388 info.mtime_.sec_ = fileStat.st_mtime;
389 info.ctime_.sec_ = fileStat.st_ctime;
390 #if !defined(CROSS_PLATFORM)
391 info.atime_.nsec_ = fileStat.st_atim.tv_nsec;
392 info.mtime_.nsec_ = fileStat.st_mtim.tv_nsec;
393 info.ctime_.nsec_ = fileStat.st_ctim.tv_nsec;
394 #endif
395 info.size_ = fileStat.st_size;
396 info.dev_ = fileStat.st_dev;
397 info.mode_ = fileStat.st_mode;
398 info.uid_ = fileStat.st_uid;
399 info.gid_ = fileStat.st_gid;
400 return std::pair{ E_OK, info };
401 }
402
ReadFileHeader(const std::string & filePath)403 std::string SqliteUtils::ReadFileHeader(const std::string &filePath)
404 {
405 constexpr int MAX_SIZE = 98;
406 std::ifstream file(filePath, std::ios::binary);
407 uint8_t data[MAX_SIZE] = {0};
408 if (file.is_open()) {
409 file.read(reinterpret_cast<char *>(data), MAX_SIZE);
410 file.close();
411 }
412 std::stringstream ss;
413 for (int i = 0; i < MAX_SIZE; i++) {
414 ss << std::hex << std::setw(DISPLAY_BYTE) << std::setfill('0') << static_cast<int>(data[i]);
415 }
416 return "DB_HEAD:" + ss.str();
417 }
418
GetFileStatInfo(const DebugInfo & debugInfo)419 std::string SqliteUtils::GetFileStatInfo(const DebugInfo &debugInfo)
420 {
421 std::stringstream oss;
422 const uint32_t permission = 0777;
423 oss << " dev:0x" << std::hex << debugInfo.dev_ << " ino:0x" << std::hex << debugInfo.inode_;
424 if (debugInfo.inode_ != debugInfo.oldInode_ && debugInfo.oldInode_ != 0) {
425 oss << "<>0x" << std::hex << debugInfo.oldInode_;
426 }
427 oss << " mode:0" << std::oct << (debugInfo.mode_ & permission) << " size:" << std::dec << debugInfo.size_
428 << " uid:" << std::dec << debugInfo.uid_ << " gid:" << std::dec << debugInfo.gid_
429 << " atim:" << RdbTimeUtils::GetTimeWithMs(debugInfo.atime_.sec_, debugInfo.atime_.nsec_)
430 << " mtim:" << RdbTimeUtils::GetTimeWithMs(debugInfo.mtime_.sec_, debugInfo.mtime_.nsec_)
431 << " ctim:" << RdbTimeUtils::GetTimeWithMs(debugInfo.ctime_.sec_, debugInfo.ctime_.nsec_);
432 return oss.str();
433 }
434
CleanFileContent(const std::string & filePath)435 bool SqliteUtils::CleanFileContent(const std::string &filePath)
436 {
437 struct stat fileStat;
438 if (stat(filePath.c_str(), &fileStat) != 0) {
439 return false;
440 }
441 if (fileStat.st_size < FILE_MAX_SIZE) {
442 return false;
443 }
444 return DeleteFile(filePath);
445 }
446
WriteSqlToFile(const std::string & comparePath,const std::string & sql)447 void SqliteUtils::WriteSqlToFile(const std::string &comparePath, const std::string &sql)
448 {
449 int fd = open(comparePath.c_str(), O_RDWR | O_CREAT, 0660);
450 if (fd == -1) {
451 LOG_ERROR("open file failed errno %{public}d %{public}s", errno, Anonymous(comparePath).c_str());
452 return ;
453 }
454 if (flock(fd, LOCK_EX) == -1) {
455 LOG_ERROR("Failed to lock file errno %{public}d %{public}s", errno, Anonymous(comparePath).c_str());
456 close(fd);
457 return ;
458 }
459 std::ofstream outFile(comparePath, std::ios::app);
460 if (!outFile) {
461 flock(fd, LOCK_UN);
462 close(fd);
463 return ;
464 }
465
466 outFile << sql << "\n";
467 outFile.close();
468 if (flock(fd, LOCK_UN) == -1) {
469 LOG_ERROR("Failed to unlock file errno %{public}d %{public}s", errno, Anonymous(comparePath).c_str());
470 }
471 close(fd);
472 }
473
GetErrInfoFromMsg(const std::string & message,const std::string & errStr)474 std::string SqliteUtils::GetErrInfoFromMsg(const std::string &message, const std::string &errStr)
475 {
476 size_t startPos = message.find(errStr);
477 std::string result;
478 if (startPos != std::string::npos) {
479 startPos += errStr.length();
480 size_t endPos = message.length();
481 result = message.substr(startPos, endPos - startPos);
482 }
483 return result;
484 }
485
CompareTableFileContent(const std::string & dbPath,const std::string & bundleName,const std::string & tableName)486 ErrMsgState SqliteUtils::CompareTableFileContent(
487 const std::string &dbPath, const std::string &bundleName, const std::string &tableName)
488 {
489 ErrMsgState state;
490 std::string compareFilePath = dbPath + "-compare";
491 std::ifstream file(compareFilePath.c_str());
492 if (!file.is_open()) {
493 LOG_ERROR("compare File open failed errno %{public}d %{public}s", errno, Anonymous(compareFilePath).c_str());
494 return state;
495 }
496
497 std::string line;
498 while (getline(file, line)) {
499 std::string target = line;
500 if (target.find(tableName) == std::string::npos) {
501 continue;
502 }
503 std::transform(target.begin(), target.end(), target.begin(), ::toupper);
504 if (target.substr(0, PREFIX_LENGTH) == "CRE") {
505 state.isCreated = true;
506 state.isDeleted = false;
507 state.isRenamed = false;
508 } else if (target.substr(0, PREFIX_LENGTH) == "DRO") {
509 state.isDeleted = true;
510 state.isRenamed = false;
511 } else if (target.substr(0, PREFIX_LENGTH) == "ALT" && target.find("RENAME") != std::string::npos) {
512 state.isDeleted = false;
513 state.isRenamed = true;
514 }
515 }
516 file.close();
517 return state;
518 }
519
CompareColumnFileContent(const std::string & dbPath,const std::string & bundleName,const std::string & columnName)520 ErrMsgState SqliteUtils::CompareColumnFileContent(
521 const std::string &dbPath, const std::string &bundleName, const std::string &columnName)
522 {
523 ErrMsgState state;
524 std::string compareFilePath = dbPath + "-compare";
525 std::ifstream file(compareFilePath.c_str());
526 if (!file.is_open()) {
527 LOG_ERROR("compare File open failed errno %{public}d %{public}s", errno, Anonymous(compareFilePath).c_str());
528 return state;
529 }
530
531 std::string line;
532 while (getline(file, line)) {
533 std::string target = line;
534 if (target.find(columnName) == std::string::npos) {
535 continue;
536 }
537 std::transform(target.begin(), target.end(), target.begin(), ::toupper);
538 if (target.substr(0, PREFIX_LENGTH) == "CRE" || (
539 target.substr(0, PREFIX_LENGTH) == "ALT" && target.find("ADD") != std::string::npos)) {
540 state.isCreated = true;
541 state.isDeleted = false;
542 state.isRenamed = false;
543 } else if (target.substr(0, PREFIX_LENGTH) == "ALT" && target.find("DROP") != std::string::npos) {
544 state.isDeleted = true;
545 state.isRenamed = false;
546 } else if (target.substr(0, PREFIX_LENGTH) == "ALT" && target.find("RENAME") != std::string::npos) {
547 state.isDeleted = false;
548 state.isRenamed = true;
549 }
550 }
551 file.close();
552 return state;
553 }
554
FormatDebugInfo(const std::map<std::string,DebugInfo> & debugs,const std::string & header)555 std::string SqliteUtils::FormatDebugInfo(const std::map<std::string, DebugInfo> &debugs, const std::string &header)
556 {
557 if (debugs.empty()) {
558 return "";
559 }
560 std::string appendix = header;
561 for (auto &[name, debugInfo] : debugs) {
562 appendix += "\n" + name + " :" + GetFileStatInfo(debugInfo);
563 }
564 return appendix;
565 }
566
FormatDebugInfoBrief(const std::map<std::string,DebugInfo> & debugs,const std::string & header)567 std::string SqliteUtils::FormatDebugInfoBrief(const std::map<std::string, DebugInfo> &debugs,
568 const std::string &header)
569 {
570 if (debugs.empty()) {
571 return "";
572 }
573 std::stringstream oss;
574 oss << header << ":";
575 for (auto &[name, debugInfo] : debugs) {
576 oss << "<" << name << ",0x" << std::hex << debugInfo.inode_ << "," << std::dec << debugInfo.size_ << ">";
577 }
578 return oss.str();
579 }
FormatDfxInfo(const DfxInfo & dfxInfo)580 std::string SqliteUtils::FormatDfxInfo(const DfxInfo &dfxInfo)
581 {
582 std::stringstream oss;
583 oss << "LastOpen:" << dfxInfo.lastOpenTime_ << "," << "CUR_USER:" << dfxInfo.curUserId_;
584 return oss.str();
585 }
586 } // namespace NativeRdb
587 } // namespace OHOS
588