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 #include <gtest/gtest.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18
19 #include <string>
20
21 #include "accesstoken_kit.h"
22 #include "common.h"
23 #include "grd_api_manager.h"
24 #include "rdb_errno.h"
25 #include "relational_store.h"
26 #include "relational_store_error_code.h"
27 #include "relational_store_impl.h"
28 #include "token_setproc.h"
29
30 using namespace testing::ext;
31 using namespace OHOS::NativeRdb;
32 using namespace OHOS::Security::AccessToken;
33 using namespace OHOS::RdbNdk;
34
35 class RdbNativeStoreConfigV2Test : public testing::Test {
36 public:
37 static void SetUpTestCase(void);
38 static void TearDownTestCase(void);
39 void SetUp();
40 void TearDown();
InitRdbConfig()41 static OH_Rdb_ConfigV2 *InitRdbConfig()
42 {
43 OH_Rdb_ConfigV2 *config = OH_Rdb_CreateConfig();
44 EXPECT_NE(config, nullptr);
45 OH_Rdb_SetDatabaseDir(config, RDB_TEST_PATH);
46 OH_Rdb_SetStoreName(config, "rdb_store_test.db");
47 OH_Rdb_SetBundleName(config, "com.ohos.example.distributedndk");
48 OH_Rdb_SetEncrypted(config, false);
49 OH_Rdb_SetSecurityLevel(config, OH_Rdb_SecurityLevel::S1);
50 OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL1);
51
52 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetDbType(config, RDB_SQLITE));
53 return config;
54 }
55 };
56
SetUpTestCase(void)57 void RdbNativeStoreConfigV2Test::SetUpTestCase(void)
58 {
59 }
60
TearDownTestCase(void)61 void RdbNativeStoreConfigV2Test::TearDownTestCase(void)
62 {
63 }
64
SetUp(void)65 void RdbNativeStoreConfigV2Test::SetUp(void)
66 {
67 }
68
TearDown(void)69 void RdbNativeStoreConfigV2Test::TearDown(void)
70 {
71 }
72
73 /**
74 * @tc.name: RDB_Native_store_test_001
75 * @tc.desc: Normal testCase of store for Update、Query.
76 * @tc.type: FUNC
77 */
78 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_001, TestSize.Level1)
79 {
80 mkdir(RDB_TEST_PATH, 0770);
81 int errCode = 0;
82 auto config = InitRdbConfig();
83 auto storeConfigV2TestRdbStore = OH_Rdb_CreateOrOpen(config, &errCode);
84 EXPECT_NE(storeConfigV2TestRdbStore, NULL);
85 char createTableSql[] = "CREATE TABLE store_test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, "
86 "data3 FLOAT, data4 BLOB, data5 TEXT);";
87 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, createTableSql));
88 char dropTableSql[] = "DROP TABLE IF EXISTS store_test";
89 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, dropTableSql));
90
91 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_CloseStore(storeConfigV2TestRdbStore));
92 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DeleteStoreV2(config));
93 OH_Rdb_DestroyConfig(config);
94 }
95
VdbTest002(const OH_Rdb_ConfigV2 * config)96 void VdbTest002(const OH_Rdb_ConfigV2 *config)
97 {
98 int errCode = OH_Rdb_ErrCode::RDB_OK;
99 auto store = OH_Rdb_CreateOrOpen(config, &errCode);
100 EXPECT_NE(store, nullptr);
101
102 char createTableSql[] = "CREATE TABLE t1(id INT PRIMARY KEY, repr floatvector(4));";
103 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, createTableSql));
104
105 int64_t trxId = 0;
106 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_BeginTransWithTrxId(store, &trxId));
107 char insertSql[] = "INSERT INTO t1 VALUES(2, '[1, 2, 3, 4]');";
108 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, trxId, insertSql));
109 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_CommitByTrxId(store, trxId));
110
111 char querySql[] = "SELECT * FROM t1;";
112 OH_Cursor *cursor = OH_Rdb_ExecuteQuery(store, querySql);
113 EXPECT_NE(cursor, nullptr);
114 int rowCount = 0;
115 cursor->getRowCount(cursor, &rowCount);
116 EXPECT_EQ(1, rowCount);
117 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, cursor->goToNextRow(cursor));
118 int64_t intVal = 0;
119 cursor->getInt64(cursor, 0, &intVal);
120 EXPECT_EQ(2, intVal); // Expect to get 2 as the result
121 cursor->destroy(cursor);
122
123 char dropSql[] = "DROP TABLE IF EXISTS t1;";
124 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, dropSql));
125
126 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DeleteStoreV2(config));
127 }
128
129 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_002, TestSize.Level1)
130 {
131 auto config = InitRdbConfig();
132 int errCode = OH_Rdb_SetDbType(config, RDB_CAYLEY);
133 EXPECT_TRUE(((!OHOS::NativeRdb::IsUsingArkData()) && errCode == OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED) ||
134 (OHOS::NativeRdb::IsUsingArkData() && errCode == OH_Rdb_ErrCode::RDB_OK));
135 if (OHOS::NativeRdb::IsUsingArkData()) {
136 VdbTest002(config);
137 }
138 OH_Rdb_DestroyConfig(config);
139 }
140
141 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_003, TestSize.Level1)
142 {
143 int numType = 0;
144 const int *supportTypeList = OH_Rdb_GetSupportedDbType(&numType);
145 EXPECT_NE(supportTypeList, nullptr);
146 EXPECT_TRUE(((!OHOS::NativeRdb::IsUsingArkData()) && numType == 1) || // 1 means only contain RDB_SQLITE
147 ((OHOS::NativeRdb::IsUsingArkData()) && numType == 2)); // 2 means both contain RDB_SQLITE and RDB_CAYLEY
148 EXPECT_EQ(RDB_SQLITE, supportTypeList[0]);
149 if (OHOS::NativeRdb::IsUsingArkData()) {
150 EXPECT_EQ(RDB_CAYLEY, supportTypeList[1]); // 1st element must be RDB_CAYLEY
151 }
152 }
153
154 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_004, TestSize.Level1)
155 {
156 auto config = InitRdbConfig();
157 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetDatabaseDir(config, nullptr));
158 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetStoreName(config, nullptr));
159 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetBundleName(config, nullptr));
160 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetModuleName(config, nullptr));
161
162 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetDatabaseDir(config, ""));
163 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetStoreName(config, ""));
164 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetBundleName(config, ""));
165 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetModuleName(config, ""));
166
167 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetEncrypted(config, false));
168 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetEncrypted(config, true));
169
170 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetSecurityLevel(config, S1));
171 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetSecurityLevel(config, S2));
172 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetSecurityLevel(config, S3));
173 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetSecurityLevel(config, S4));
174 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetSecurityLevel(config, 0)); // 0 is invalid secure level
175 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetSecurityLevel(config, -1)); // -1 is invalid secure level
176 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetSecurityLevel(config, 5)); // 5 is invalid secure level
177
178 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL1));
179 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL2));
180 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL3));
181 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL4));
182 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetArea(config, RDB_SECURITY_AREA_EL5));
183
184 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetArea(config, -1)); // -1 is invalid area level
185 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetArea(config, 0)); // 0 is invalid area level
186 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetArea(config, 8)); // 8 is invalid area level
187
188 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetDbType(config, RDB_SQLITE));
189 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetDbType(config, 0)); // 0 is invalid db type level
190 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetDbType(config, 6)); // 6 is invalid db type level
191 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_SetDbType(config, -1)); // -1 is invalid db type level
192
193 const int *supportList = OH_Rdb_GetSupportedDbType(nullptr);
194 EXPECT_EQ(nullptr, supportList);
195
196 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, OH_Rdb_DestroyConfig(nullptr));
197 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DestroyConfig(config));
198 }
199
VdbTest003(const OH_Rdb_ConfigV2 * config)200 void VdbTest003(const OH_Rdb_ConfigV2 *config)
201 {
202 int errCode = OH_Rdb_ErrCode::RDB_OK;
203 auto store = OH_Rdb_CreateOrOpen(config, &errCode);
204 EXPECT_NE(store, nullptr);
205
206 char createTableSql[] = "CREATE TABLE t1(id INT PRIMARY KEY, repr floatvector(4));";
207 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, createTableSql));
208
209 char createIndexSql[] = "CREATE INDEX diskann_idx ON t1 USING GSDISKANN(repr L2);";
210 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, createIndexSql));
211
212 int64_t trxId = 0;
213 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_BeginTransWithTrxId(store, &trxId));
214 char insertSql[] = "INSERT INTO t1 VALUES(1, '[1, 2, 3, 4]');";
215 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, trxId, insertSql));
216 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_CommitByTrxId(store, trxId));
217
218 char insertSql2[] = "INSERT INTO t1 VALUES(2, '[2, 2, 3, 4]');";
219 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, insertSql2));
220
221 char deleteSql[] = "DELETE FROM t1 WHERE id = 1;";
222 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, deleteSql));
223
224 char dropSql[] = "DROP TABLE IF EXISTS t1;";
225 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, dropSql));
226
227 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DeleteStoreV2(config));
228 }
229
230 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_005, TestSize.Level1)
231 {
232 auto config = InitRdbConfig();
233 int errCode = OH_Rdb_SetDbType(config, RDB_CAYLEY);
234 EXPECT_TRUE(((!OHOS::NativeRdb::IsUsingArkData()) && errCode == OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED) ||
235 (OHOS::NativeRdb::IsUsingArkData() && errCode == OH_Rdb_ErrCode::RDB_OK));
236 if (OHOS::NativeRdb::IsUsingArkData()) {
237 VdbTest003(config);
238 }
239 OH_Rdb_DestroyConfig(config);
240 }
241
GetRandVector(uint32_t maxElementNum,uint16_t dim)242 string GetRandVector(uint32_t maxElementNum, uint16_t dim)
243 {
244 auto now = std::chrono::high_resolution_clock::now();
245 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
246 unsigned int randomNumberSeed = static_cast<unsigned int>(ns);
247 std::string res = "[";
248 for (uint16_t i = 0; i < dim; i++) {
249 uint32_t intPart = maxElementNum == 0 ? 0 : (rand_r(&randomNumberSeed) % maxElementNum);
250 intPart += 1;
251 // 10 is used to limit the number after the decimal point to a maximum of 10.
252 uint32_t tenths = (rand_r(&randomNumberSeed) % 10);
253 res += std::to_string(intPart);
254 res += ".000";
255 res += std::to_string(tenths);
256 res += ", ";
257 }
258 res.pop_back();
259 res.pop_back();
260 res += "]";
261 return res;
262 }
263
VdbTest004(const OH_Rdb_ConfigV2 * config)264 void VdbTest004(const OH_Rdb_ConfigV2 *config)
265 {
266 int errCode = OH_Rdb_ErrCode::RDB_OK;
267 auto store = OH_Rdb_CreateOrOpen(config, &errCode);
268 EXPECT_NE(store, nullptr);
269
270 char createTableSql[] = "CREATE TABLE t1(id INT PRIMARY KEY, repr floatvector(4));";
271 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, createTableSql));
272
273 char createIndexSql[] = "CREATE INDEX diskann_idx ON t1 USING GSDISKANN(repr L2);";
274 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, createIndexSql));
275
276 uint32_t maxIntPart = 100;
277 uint32_t numSamples = 100;
278 uint32_t dim = 4;
279
280 for (uint16_t i = 0; i < numSamples; i++) {
281 std::string sqlInsert =
282 "INSERT INTO t1 VALUES(" + std::to_string(i) + ", '" + GetRandVector(maxIntPart, dim) + "');";
283 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, sqlInsert.data()));
284 }
285 for (uint16_t i = 0; i < numSamples; i++) {
286 std::string sqlDelete = "DELETE FROM t1 WHERE id = " + std::to_string(i) + ";";
287 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, sqlDelete.data()));
288 }
289
290 char dropSql[] = "DROP TABLE IF EXISTS t1;";
291 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_ExecuteByTrxId(store, 0, dropSql));
292
293 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DeleteStoreV2(config));
294 }
295
296 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_006, TestSize.Level1)
297 {
298 auto config = InitRdbConfig();
299 int errCode = OH_Rdb_SetDbType(config, RDB_CAYLEY);
300 EXPECT_TRUE(((!OHOS::NativeRdb::IsUsingArkData()) && errCode == OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED) ||
301 (OHOS::NativeRdb::IsUsingArkData() && errCode == OH_Rdb_ErrCode::RDB_OK));
302 if (OHOS::NativeRdb::IsUsingArkData()) {
303 VdbTest004(config);
304 }
305 OH_Rdb_DestroyConfig(config);
306 }
307
308 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_Native_store_test_007, TestSize.Level1)
309 {
310 auto config = InitRdbConfig();
311 int errCode = OH_Rdb_SetPersistent(config, true);
312 EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_OK);
313 errCode = OH_Rdb_SetPersistent(config, false);
314 EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_OK);
315 OH_Rdb_DestroyConfig(config);
316 }
317
318 /**
319 * @tc.name: RDB_ICU_TEST001
320 * @tc.desc: test apis of icu
321 * @tc.type: FUNC
322 */
323 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_ICU_TEST001, TestSize.Level1)
324 {
325 mkdir(RDB_TEST_PATH, 0770);
326 auto config = InitRdbConfig();
327
328 // invalid param test
329 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS,
330 OH_Rdb_SetTokenizer(config, static_cast<Rdb_Tokenizer>(Rdb_Tokenizer::RDB_NONE_TOKENIZER - 1)));
331 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_INVALID_ARGS,
332 OH_Rdb_SetTokenizer(config, static_cast<Rdb_Tokenizer>(Rdb_Tokenizer::RDB_CUSTOM_TOKENIZER + 1)));
333
334 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetTokenizer(config, Rdb_Tokenizer::RDB_NONE_TOKENIZER));
335 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetTokenizer(config, Rdb_Tokenizer::RDB_CUSTOM_TOKENIZER));
336 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetTokenizer(config, Rdb_Tokenizer::RDB_ICU_TOKENIZER));
337
338 int numType = 0;
339 const int *supportTypeList = OH_Rdb_GetSupportedDbType(&numType);
340 EXPECT_NE(supportTypeList, nullptr);
341 if (numType == 2) {
342 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetDbType(config, RDB_CAYLEY));
343 EXPECT_EQ(OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED,
344
345 OH_Rdb_SetTokenizer(config, Rdb_Tokenizer::RDB_ICU_TOKENIZER));
346 }
347
348 OH_Rdb_DestroyConfig(config);
349 }
350
351 /**
352 * @tc.name: RDB_ICU_TEST002
353 * @tc.desc: test apis of icu
354 * @tc.type: FUNC
355 */
356 HWTEST_F(RdbNativeStoreConfigV2Test, RDB_ICU_TEST002, TestSize.Level1)
357 {
358 mkdir(RDB_TEST_PATH, 0770);
359 int errCode = 0;
360 auto config = InitRdbConfig();
361
362 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_SetTokenizer(config, Rdb_Tokenizer::RDB_ICU_TOKENIZER));
363 auto storeConfigV2TestRdbStore = OH_Rdb_CreateOrOpen(config, &errCode);
364 EXPECT_NE(storeConfigV2TestRdbStore, NULL);
365
366 char createTableSql[] = "CREATE VIRTUAL TABLE example USING fts4(name, content, tokenize=icu zh_CN);";
367 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, createTableSql));
368
369 char insertSql1[] =
370 "INSERT INTO example(name, content) VALUES('文档1', '这是一个测试文档,用于测试中文文本的分词和索引。');";
371 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, insertSql1));
372
373 char insertSql2[] =
374 "INSERT INTO example(name, content) VALUES('文档2', '我们将使用这个示例来演示如何在SQLite中进行全文搜索。');";
375 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, insertSql2));
376
377 char insertSql3[] =
378 "INSERT INTO example(name, content) VALUES('文档3', 'ICU分词器能够很好地处理中文文本的分词和分析。');";
379 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, insertSql3));
380
381 char querySql[] = "SELECT * FROM example WHERE example MATCH '测试';";
382 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_Execute(storeConfigV2TestRdbStore, querySql));
383
384 OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeConfigV2TestRdbStore, querySql);
385 EXPECT_NE(cursor, nullptr);
386 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, cursor->goToNextRow(cursor));
387
388 int columnIndex = -1;
389 errCode = cursor->getColumnIndex(cursor, "name", &columnIndex);
390 EXPECT_EQ(columnIndex, 0);
391 char name[10];
392 errCode = cursor->getColumnName(cursor, columnIndex, name, 10);
393 EXPECT_EQ(strcmp(name, "name"), 0);
394
395 size_t size = 0;
396 cursor->getSize(cursor, columnIndex, &size);
397 char data1Value[size + 1];
398 cursor->getText(cursor, columnIndex, data1Value, size + 1);
399 EXPECT_EQ(strcmp(data1Value, "文档1"), 0);
400
401 errCode = cursor->getColumnIndex(cursor, "content", &columnIndex);
402 char name2[10];
403 errCode = cursor->getColumnName(cursor, columnIndex, name2, 10);
404 EXPECT_EQ(strcmp(name2, "content"), 0);
405
406 cursor->getSize(cursor, columnIndex, &size);
407 char data2Value[size + 1];
408 cursor->getText(cursor, columnIndex, data2Value, size + 1);
409 EXPECT_EQ(strcmp(data2Value, "这是一个测试文档,用于测试中文文本的分词和索引。"), 0);
410
411 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_CloseStore(storeConfigV2TestRdbStore));
412 EXPECT_EQ(OH_Rdb_ErrCode::RDB_OK, OH_Rdb_DeleteStoreV2(config));
413 OH_Rdb_DestroyConfig(config);
414 }
415