• 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 
16 #include "distributeddb_tools_unit_test.h"
17 #include "platform_specific.h"
18 
19 using namespace DistributedDB;
20 
21 namespace DistributedDBUnitTest {
GetCurrentDir(std::string & dir)22 int DistributedDBToolsUnitTest::GetCurrentDir(std::string &dir)
23 {
24     static const int maxFileLength = 1024;
25     dir = "";
26     char buffer[maxFileLength] = {0};
27     int length = readlink("/proc/self/exe", buffer, maxFileLength);
28     if (length < 0 || length >= maxFileLength) {
29         LOGE("read directory err length:%d", length);
30         return -E_LENGTH_ERROR;
31     }
32     LOGD("DIR = %s", buffer);
33     dir = buffer;
34     if (dir.rfind("/") == std::string::npos && dir.rfind("\\") == std::string::npos) {
35         LOGE("current patch format err");
36         return -E_INVALID_PATH;
37     }
38 
39     if (dir.rfind("/") != std::string::npos) {
40         dir.erase(dir.rfind("/") + 1);
41     }
42     return E_OK;
43 }
44 
TestDirInit(std::string & dir)45 void DistributedDBToolsUnitTest::TestDirInit(std::string &dir)
46 {
47     if (GetCurrentDir(dir) != E_OK) {
48         dir = "/";
49     }
50 
51     dir.append("testDbDir");
52     DIR *dirTmp = opendir(dir.c_str());
53     if (dirTmp == nullptr) {
54         if (OS::MakeDBDirectory(dir) != 0) {
55             LOGI("MakeDirectory err!");
56             dir = "/";
57             return;
58         }
59     } else {
60         closedir(dirTmp);
61     }
62 }
63 
RemoveTestDbFiles(const std::string & dir)64 int DistributedDBToolsUnitTest::RemoveTestDbFiles(const std::string &dir)
65 {
66     bool isExisted = OS::CheckPathExistence(dir);
67     if (!isExisted) {
68         return E_OK;
69     }
70 
71     int nFile = 0;
72     std::string dirName;
73     struct dirent *direntPtr = nullptr;
74     DIR *dirPtr = opendir(dir.c_str());
75     if (dirPtr == nullptr) {
76         LOGE("opendir error!");
77         return -E_INVALID_PATH;
78     }
79     while (true) {
80         direntPtr = readdir(dirPtr);
81         // condition to exit the loop
82         if (direntPtr == nullptr) {
83             break;
84         }
85         // only remove all *.db files
86         std::string str(direntPtr->d_name);
87         if (str == "." || str == "..") {
88             continue;
89         }
90         dirName.clear();
91         dirName.append(dir).append("/").append(str);
92         if (direntPtr->d_type == DT_DIR) {
93             RemoveTestDbFiles(dirName);
94             rmdir(dirName.c_str());
95         } else if (remove(dirName.c_str()) != 0) {
96             LOGI("remove file: %s failed!", dirName.c_str());
97             continue;
98         }
99         nFile++;
100     }
101     closedir(dirPtr);
102     LOGI("Total %d test db files are removed!", nFile);
103     return 0;
104 }
105 
CreateDataBase(const std::string & dbUri)106 sqlite3 *RelationalTestUtils::CreateDataBase(const std::string &dbUri)
107 {
108     LOGD("Create database: %s", dbUri.c_str());
109     sqlite3 *db = nullptr;
110     if (int r = sqlite3_open_v2(dbUri.c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr) != SQLITE_OK) {
111         LOGE("Open database [%s] failed. %d", dbUri.c_str(), r);
112         if (db != nullptr) {
113             (void)sqlite3_close_v2(db);
114             db = nullptr;
115         }
116     }
117     return db;
118 }
119 
ExecSql(sqlite3 * db,const std::string & sql)120 int RelationalTestUtils::ExecSql(sqlite3 *db, const std::string &sql)
121 {
122     if (db == nullptr || sql.empty()) {
123         return -E_INVALID_ARGS;
124     }
125     char *errMsg = nullptr;
126     int errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg);
127     if (errCode != SQLITE_OK && errMsg != nullptr) {
128         LOGE("Execute sql failed. %d err: %s", errCode, errMsg);
129     }
130     sqlite3_free(errMsg);
131     return errCode;
132 }
133 
ExecSql(sqlite3 * db,const std::string & sql,const std::function<int (sqlite3_stmt *)> & bindCallback,const std::function<int (sqlite3_stmt *)> & resultCallback)134 int RelationalTestUtils::ExecSql(sqlite3 *db, const std::string &sql,
135     const std::function<int (sqlite3_stmt *)> &bindCallback, const std::function<int (sqlite3_stmt *)> &resultCallback)
136 {
137     if (db == nullptr || sql.empty()) {
138         return -E_INVALID_ARGS;
139     }
140 
141     bool bindFinish = true;
142     sqlite3_stmt *stmt = nullptr;
143     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
144     if (errCode != E_OK) {
145         goto END;
146     }
147 
148     do {
149         if (bindCallback) {
150             errCode = bindCallback(stmt);
151             if (errCode != E_OK && errCode != -E_UNFINISHED) {
152                 goto END;
153             }
154             bindFinish = (errCode != -E_UNFINISHED); // continue bind if unfinished
155         }
156 
157         bool isStepFinished = false;
158         while (!isStepFinished) {
159             errCode = SQLiteUtils::StepWithRetry(stmt);
160             if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
161                 errCode = E_OK; // Step finished
162                 isStepFinished = true;
163                 break;
164             } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
165                 goto END; // Step return error
166             }
167             if (resultCallback == nullptr) {
168                 continue;
169             }
170             errCode = resultCallback(stmt);
171             if (errCode != E_OK) {
172                 goto END;
173             }
174         }
175         SQLiteUtils::ResetStatement(stmt, false, errCode);
176     } while (!bindFinish);
177 
178 END:
179     SQLiteUtils::ResetStatement(stmt, true, errCode);
180     return errCode;
181 }
182 } // namespace DistributedDBUnitTest
183