1 /*
2 * Copyright (c) 2022 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 #ifndef OMIT_JSON
17 #include <gtest/gtest.h>
18 #include <cmath>
19
20 #include "db_errno.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "log_print.h"
23 #include "relational_schema_object.h"
24 #include "schema_utils.h"
25 #include "schema_constant.h"
26 #include "schema_negotiate.h"
27
28 using namespace std;
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32
33 namespace {
34 constexpr const char* DB_SUFFIX = ".db";
35 constexpr const char* STORE_ID = "Relational_Store_ID";
36 string g_testDir;
37 string g_dbDir;
38
39 const std::string NORMAL_SCHEMA = R""({
40 "SCHEMA_VERSION": "2.0",
41 "SCHEMA_TYPE": "RELATIVE",
42 "TABLES": [{
43 "NAME": "FIRST",
44 "DEFINE": {
45 "field_name1": {
46 "COLUMN_ID":1,
47 "TYPE": "STRING",
48 "NOT_NULL": true,
49 "DEFAULT": "abcd"
50 },
51 "field_name2": {
52 "COLUMN_ID":2,
53 "TYPE": "MYINT(21)",
54 "NOT_NULL": false,
55 "DEFAULT": "222"
56 },
57 "field_name3": {
58 "COLUMN_ID":3,
59 "TYPE": "INTGER",
60 "NOT_NULL": false,
61 "DEFAULT": "1"
62 }
63 },
64 "AUTOINCREMENT": true,
65 "UNIQUE": [["field_name1"], ["field_name2", "field_name3"]],
66 "PRIMARY_KEY": "field_name1",
67 "INDEX": {
68 "index_name1": ["field_name1", "field_name2"],
69 "index_name2": ["field_name3"]
70 }
71 }, {
72 "NAME": "SECOND",
73 "DEFINE": {
74 "key": {
75 "COLUMN_ID":1,
76 "TYPE": "BLOB",
77 "NOT_NULL": true
78 },
79 "value": {
80 "COLUMN_ID":2,
81 "TYPE": "BLOB",
82 "NOT_NULL": false
83 }
84 },
85 "PRIMARY_KEY": "field_name1"
86 }]
87 })"";
88
89 const std::string NORMAL_SCHEMA_V2_1 = R""({
90 "SCHEMA_VERSION": "2.1",
91 "SCHEMA_TYPE": "RELATIVE",
92 "TABLE_MODE": "SPLIT_BY_DEVICE",
93 "TABLES": [{
94 "NAME": "FIRST",
95 "DEFINE": {
96 "field_name1": {
97 "COLUMN_ID":1,
98 "TYPE": "STRING",
99 "NOT_NULL": true,
100 "DEFAULT": "abcd"
101 },
102 "field_name2": {
103 "COLUMN_ID":2,
104 "TYPE": "MYINT(21)",
105 "NOT_NULL": false,
106 "DEFAULT": "222"
107 },
108 "field_name3": {
109 "COLUMN_ID":3,
110 "TYPE": "INTGER",
111 "NOT_NULL": false,
112 "DEFAULT": "1"
113 }
114 },
115 "AUTOINCREMENT": true,
116 "UNIQUE": [["field_name1"], ["field_name2", "field_name3"]],
117 "PRIMARY_KEY": ["field_name1", "field_name3"],
118 "INDEX": {
119 "index_name1": ["field_name1", "field_name2"],
120 "index_name2": ["field_name3"]
121 }
122 }, {
123 "NAME": "SECOND",
124 "DEFINE": {
125 "key": {
126 "COLUMN_ID":1,
127 "TYPE": "BLOB",
128 "NOT_NULL": true
129 },
130 "value": {
131 "COLUMN_ID":2,
132 "TYPE": "BLOB",
133 "NOT_NULL": false
134 }
135 },
136 "PRIMARY_KEY": ["field_name1"]
137 }]
138 })"";
139
140 const std::string INVALID_SCHEMA = R""({
141 "SCHEMA_VERSION": "2.0",
142 "SCHEMA_TYPE": "RELATIVE",
143 "TABLES": [{
144 "NAME": "FIRST",
145 "DEFINE": {
146 "field_name1": {
147 "COLUMN_ID":1,
148 "TYPE": "STRING",
149 "NOT_NULL": true,
150 "DEFAULT": "abcd"
151 },"field_name2": {
152 "COLUMN_ID":2,
153 "TYPE": "MYINT(21)",
154 "NOT_NULL": false,
155 "DEFAULT": "222"
156 }
157 },
158 "PRIMARY_KEY": "field_name1"
159 }]
160 })"";
161
162 const std::string INVALID_JSON_STRING = R""({
163 "SCHEMA_VERSION": "2.0",
164 "SCHEMA_TYPE": "RELATIVE",
165 "TABLES": [{
166 "NAME": "FIRST",
167 "DEFINE": {
168 "field_name1": {)"";
169
170 const std::string SCHEMA_VERSION_STR_1 = R"("SCHEMA_VERSION": "1.0",)";
171 const std::string SCHEMA_VERSION_STR_2 = R"("SCHEMA_VERSION": "2.0",)";
172 const std::string SCHEMA_VERSION_STR_2_1 = R"("SCHEMA_VERSION": "2.1",)";
173 const std::string SCHEMA_VERSION_STR_INVALID = R"("SCHEMA_VERSION": "awd3",)";
174 const std::string SCHEMA_TYPE_STR_NONE = R"("SCHEMA_TYPE": "NONE",)";
175 const std::string SCHEMA_TYPE_STR_JSON = R"("SCHEMA_TYPE": "JSON",)";
176 const std::string SCHEMA_TYPE_STR_FLATBUFFER = R"("SCHEMA_TYPE": "FLATBUFFER",)";
177 const std::string SCHEMA_TYPE_STR_RELATIVE = R"("SCHEMA_TYPE": "RELATIVE",)";
178 const std::string SCHEMA_TYPE_STR_INVALID = R"("SCHEMA_TYPE": "adewaaSAD",)";
179 const std::string SCHEMA_TABLE_MODE_COLLABORATION = R"("TABLE_MODE": "COLLABORATION",)";
180 const std::string SCHEMA_TABLE_MODE_SPLIT_BY_DEVICE = R"("TABLE_MODE": "SPLIT_BY_DEVICE",)";
181 const std::string SCHEMA_TABLE_MODE_INVALID = R"("TABLE_MODE": "SPLIT_BY_USER",)";
182 const std::string DISTRIBUTED_VALID_VERSION = R"("DISTRIBUTED_SCHEMA": { "VERSION": 1 })";
183 const std::string DISTRIBUTED_INVALID_SMALL_VERSION = R"("DISTRIBUTED_SCHEMA": { "VERSION": -1 })";
184 const std::string DISTRIBUTED_INVALID_LARGE_VERSION = R"("DISTRIBUTED_SCHEMA": { "VERSION": 5000000000 })";
185 const std::string DISTRIBUTED_INVALID_NAN_VERSION = R"("DISTRIBUTED_SCHEMA": { "VERSION": "not a number" })";
186
187 const std::string SCHEMA_TABLE_STR = R""("TABLES": [{
188 "NAME": "FIRST",
189 "DEFINE": {
190 "field_name1": {
191 "COLUMN_ID":1,
192 "TYPE": "STRING",
193 "NOT_NULL": true,
194 "DEFAULT": "abcd"
195 },"field_name2": {
196 "COLUMN_ID":2,
197 "TYPE": "MYINT(21)",
198 "NOT_NULL": false,
199 "DEFAULT": "222"
200 }
201 },
202 "PRIMARY_KEY": "field_name1"
203 }])"";
204
205 const std::string TABLE_DEFINE_STR = R""({
206 "NAME": "FIRST",
207 "DEFINE": {
208 "field_name1": {
209 "COLUMN_ID":1,
210 "TYPE": "STRING",
211 "NOT_NULL": true,
212 "DEFAULT": "abcd"
213 },"field_name2": {
214 "COLUMN_ID":2,
215 "TYPE": "MYINT(21)",
216 "NOT_NULL": false,
217 "DEFAULT": "222"
218 }
219 },
220 "PRIMARY_KEY": "field_name1"
221 })"";
222
223 const std::string TABLE_DEFINE_STR_NAME = R""("NAME": "FIRST",)"";
224 const std::string TABLE_DEFINE_STR_NAME_INVALID = R"("NAME": 123,)";
225 const std::string TABLE_DEFINE_STR_NAME_INVALID_CHARACTER = R"("NAME": "t1; --",)";
226 const std::string TABLE_DEFINE_STR_FIELDS = R""("DEFINE": {
227 "field_name1": {
228 "COLUMN_ID":1,
229 "TYPE": "STRING",
230 "NOT_NULL": true,
231 "DEFAULT": "abcd"
232 },"field_name2": {
233 "COLUMN_ID":2,
234 "TYPE": "MYINT(21)",
235 "NOT_NULL": false,
236 "DEFAULT": "222"
237 }
238 },)"";
239 const std::string TABLE_DEFINE_STR_FIELDS_EMPTY = R""("DEFINE": {},)"";
240 const std::string TABLE_DEFINE_STR_FIELDS_NOTYPE = R""("DEFINE": {
241 "field_name1": {
242 "COLUMN_ID":1,
243 "NOT_NULL": true,
244 "DEFAULT": "abcd"
245 }},)"";
246 const std::string TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER = R""("DEFINE": {
247 "1 = 1; --": {
248 "COLUMN_ID":1,
249 "NOT_NULL": true,
250 "DEFAULT": "abcd"
251 }},)"";
252 const std::string TABLE_DEFINE_STR_KEY = R""("PRIMARY_KEY": "field_name1")"";
253 const std::string TABLE_DEFINE_BOOL_KEY_INVALID = R""("PRIMARY_KEY": false)"";
254 const std::string TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID = R""("PRIMARY_KEY": [false, true, true])"";
255 }
256
257 class DistributedDBRelationalSchemaObjectTest : public testing::Test {
258 public:
259 static void SetUpTestCase(void);
260 static void TearDownTestCase(void);
261 void SetUp() override;
262 void TearDown() override;
263 };
264
SetUpTestCase(void)265 void DistributedDBRelationalSchemaObjectTest::SetUpTestCase(void)
266 {
267 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
268 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
269 LOGI("The test db is:%s", g_testDir.c_str());
270 g_dbDir = g_testDir + "/";
271 }
272
TearDownTestCase(void)273 void DistributedDBRelationalSchemaObjectTest::TearDownTestCase(void)
274 {
275 }
276
SetUp()277 void DistributedDBRelationalSchemaObjectTest::SetUp()
278 {
279 DistributedDBToolsUnitTest::PrintTestCaseInfo();
280 }
281
TearDown()282 void DistributedDBRelationalSchemaObjectTest::TearDown()
283 {
284 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
285 LOGE("rm test db files error.");
286 }
287 return;
288 }
289
290 /**
291 * @tc.name: RelationalSchemaParseTest001
292 * @tc.desc: Test relational schema parse from json string
293 * @tc.type: FUNC
294 * @tc.require:
295 * @tc.author: lianhuix
296 */
297 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest001, TestSize.Level1)
298 {
299 const std::string schemaStr = NORMAL_SCHEMA;
300 RelationalSchemaObject schemaObj;
301 int errCode = schemaObj.ParseFromSchemaString(schemaStr);
302 EXPECT_EQ(errCode, E_OK);
303 EXPECT_EQ(schemaObj.GetTable("FIRST").GetUniqueDefine().size(), 2u);
304
305 RelationalSchemaObject schemaObj2;
306 schemaObj2.ParseFromSchemaString(schemaObj.ToSchemaString());
307 EXPECT_EQ(errCode, E_OK);
308 EXPECT_EQ(schemaObj2.GetTable("FIRST").GetUniqueDefine().size(), 2u);
309
310 RelationalSyncOpinion op = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, schemaObj2.ToSchemaString(),
311 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
312
313 EXPECT_EQ(op.size(), 2u);
314 EXPECT_EQ(op.at("FIRST").permitSync, true);
315 EXPECT_EQ(op.at("SECOND").permitSync, true);
316 }
317
318 /**
319 * @tc.name: RelationalSchemaParseTest002
320 * @tc.desc: Test relational schema parse from invalid json string
321 * @tc.type: FUNC
322 * @tc.require:
323 * @tc.author: lianhuix
324 */
325 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest002, TestSize.Level1)
326 {
327 RelationalSchemaObject schemaObj;
328
329 std::string schemaStr01(SchemaConstant::SCHEMA_STRING_SIZE_LIMIT + 1, 's');
330 int errCode = schemaObj.ParseFromSchemaString(schemaStr01);
331 EXPECT_EQ(errCode, -E_INVALID_ARGS);
332
333 errCode = schemaObj.ParseFromSchemaString(INVALID_JSON_STRING);
334 EXPECT_EQ(errCode, -E_JSON_PARSE_FAIL);
335
336 std::string noVersion = "{" + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
337 errCode = schemaObj.ParseFromSchemaString(noVersion);
338 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
339
340 std::string invalidVersion1 = "{" + SCHEMA_VERSION_STR_1 + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
341 errCode = schemaObj.ParseFromSchemaString(invalidVersion1);
342 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
343
344 std::string invalidVersion2 = "{" + SCHEMA_VERSION_STR_INVALID + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}";
345 errCode = schemaObj.ParseFromSchemaString(invalidVersion2);
346 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
347
348 std::string noType = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TABLE_STR + "}";
349 errCode = schemaObj.ParseFromSchemaString(noType);
350 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
351
352 std::string invalidType1 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_NONE + SCHEMA_TABLE_STR + "}";
353 errCode = schemaObj.ParseFromSchemaString(invalidType1);
354 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
355
356 std::string invalidType2 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_JSON + SCHEMA_TABLE_STR + "}";
357 errCode = schemaObj.ParseFromSchemaString(invalidType2);
358 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
359
360 std::string invalidType3 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_FLATBUFFER + SCHEMA_TABLE_STR + "}";
361 errCode = schemaObj.ParseFromSchemaString(invalidType3);
362 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
363
364 std::string invalidType4 = "{" + SCHEMA_VERSION_STR_2 + SCHEMA_TYPE_STR_INVALID + SCHEMA_TABLE_STR + "}";
365 errCode = schemaObj.ParseFromSchemaString(invalidType4);
366 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
367
368 std::string noTable = "{" + SCHEMA_VERSION_STR_2 +
369 SCHEMA_TYPE_STR_RELATIVE.substr(0, SCHEMA_TYPE_STR_RELATIVE.length() - 1) + "}";
370 errCode = schemaObj.ParseFromSchemaString(noTable);
371 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
372 }
373
374 namespace {
GenerateFromTableStr(const std::string & tableStr)375 std::string GenerateFromTableStr(const std::string &tableStr)
376 {
377 return R""({
378 "SCHEMA_VERSION": "2.0",
379 "SCHEMA_TYPE": "RELATIVE",
380 "TABLES": )"" + tableStr + "}";
381 }
382 }
383
384 /**
385 * @tc.name: RelationalSchemaParseTest003
386 * @tc.desc: Test relational schema parse from invalid json string
387 * @tc.type: FUNC
388 * @tc.require:
389 * @tc.author: lianhuix
390 */
391 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest003, TestSize.Level1)
392 {
393 RelationalSchemaObject schemaObj;
394 int errCode = E_OK;
395
396 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr(TABLE_DEFINE_STR));
397 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
398
399 std::string invalidTableStr01 = "{" + TABLE_DEFINE_STR_FIELDS + TABLE_DEFINE_STR_KEY + "}";
400 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr01 + "]"));
401 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
402
403 std::string invalidTableStr02 = "{" + TABLE_DEFINE_STR_NAME_INVALID + TABLE_DEFINE_STR_FIELDS +
404 TABLE_DEFINE_STR_KEY + "}";
405 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr02 + "]"));
406 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
407
408 std::string invalidTableStr04 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS_NOTYPE +
409 TABLE_DEFINE_STR_KEY + "}";
410 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr04 + "]"));
411 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
412
413 std::string invalidTableStr05 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS +
414 TABLE_DEFINE_BOOL_KEY_INVALID + "}";
415 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr05 + "]"));
416 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
417
418 std::string invalidTableStr06 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS +
419 TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID + "}";
420 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr06 + "]"));
421 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
422
423 std::string invalidTableStr07 = "{" + TABLE_DEFINE_STR_NAME_INVALID_CHARACTER + TABLE_DEFINE_STR_FIELDS +
424 TABLE_DEFINE_STR_KEY + "}";
425 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr07 + "]"));
426 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
427
428 std::string invalidTableStr08 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER +
429 TABLE_DEFINE_STR_KEY + "}";
430 errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr08 + "]"));
431 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
432
433 errCode = schemaObj.ParseFromSchemaString("");
434 EXPECT_EQ(errCode, -E_INVALID_ARGS);
435 }
436
437 /**
438 * @tc.name: RelationalSchemaParseTest004
439 * @tc.desc:
440 * @tc.type: FUNC
441 * @tc.require:
442 * @tc.author: lianhuix
443 */
444 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest004, TestSize.Level1)
445 {
446 RelationalSchemaObject schemaObj;
447 int errCode = E_OK;
448
449 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_COLLABORATION + SCHEMA_TYPE_STR_RELATIVE +
450 SCHEMA_TABLE_STR + "}";
451 errCode = schemaObj.ParseFromSchemaString(schema);
452 EXPECT_EQ(errCode, E_OK);
453 }
454
455 /**
456 * @tc.name: RelationalSchemaParseTest005
457 * @tc.desc:
458 * @tc.type: FUNC
459 * @tc.require:
460 * @tc.author: lianhuix
461 */
462 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest005, TestSize.Level1)
463 {
464 RelationalSchemaObject schemaObj;
465 int errCode = E_OK;
466
467 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_SPLIT_BY_DEVICE + SCHEMA_TYPE_STR_RELATIVE +
468 SCHEMA_TABLE_STR + "}";
469 errCode = schemaObj.ParseFromSchemaString(schema);
470 EXPECT_EQ(errCode, E_OK);
471 }
472
473 /**
474 * @tc.name: RelationalSchemaParseTest006
475 * @tc.desc:
476 * @tc.type: FUNC
477 * @tc.require:
478 * @tc.author: lianhuix
479 */
480 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest006, TestSize.Level1)
481 {
482 RelationalSchemaObject schemaObj;
483 int errCode = E_OK;
484
485 std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_INVALID + SCHEMA_TYPE_STR_RELATIVE +
486 SCHEMA_TABLE_STR + "}";
487 errCode = schemaObj.ParseFromSchemaString(schema);
488 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
489 }
490
491 /**
492 * @tc.name: RelationalSchemaParseTest007
493 * @tc.desc: test parse for distributed version in schema
494 * @tc.type: FUNC
495 * @tc.require:
496 * @tc.author: liuhongyang
497 */
498 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest007, TestSize.Level1)
499 {
500 RelationalSchemaObject schemaObj;
501 std::string schemaOtherField = SCHEMA_VERSION_STR_2_1 + SCHEMA_TABLE_MODE_COLLABORATION + SCHEMA_TYPE_STR_RELATIVE +
502 SCHEMA_TABLE_STR + ",";
503 /**
504 * @tc.steps: step1. call ParseFromSchemaString with a version less than the min of uint32_t
505 * @tc.expected: step1. return -E_SCHEMA_PARSE_FAIL.
506 */
507 std::string schema = "{" + schemaOtherField + DISTRIBUTED_INVALID_SMALL_VERSION + "}";
508 int errCode = schemaObj.ParseFromSchemaString(schema);
509 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
510 /**
511 * @tc.steps: step2. call ParseFromSchemaString with a version greater than the max of uint32_t
512 * @tc.expected: step2. return -E_SCHEMA_PARSE_FAIL.
513 */
514 schema = "{" + schemaOtherField + DISTRIBUTED_INVALID_LARGE_VERSION + "}";
515 errCode = schemaObj.ParseFromSchemaString(schema);
516 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
517 /**
518 * @tc.steps: step3. call ParseFromSchemaString with a version that is not a number
519 * @tc.expected: step3. return -E_SCHEMA_PARSE_FAIL.
520 */
521 schema = "{" + schemaOtherField + DISTRIBUTED_INVALID_NAN_VERSION + "}";
522 errCode = schemaObj.ParseFromSchemaString(schema);
523 EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL);
524 /**
525 * @tc.steps: step4. call ParseFromSchemaString with a normal version
526 * @tc.expected: step4. return E_OK.
527 */
528 schema = "{" + schemaOtherField + DISTRIBUTED_VALID_VERSION + "}";
529 errCode = schemaObj.ParseFromSchemaString(schema);
530 EXPECT_EQ(errCode, E_OK);
531 }
532
533 /**
534 * @tc.name: RelationalSchemaCompareTest001
535 * @tc.desc: Test relational schema negotiate with same schema string
536 * @tc.type: FUNC
537 * @tc.require:
538 * @tc.author: lianhuix
539 */
540 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest001, TestSize.Level1)
541 {
542 RelationalSchemaObject schemaObj;
543 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
544 EXPECT_EQ(errCode, E_OK);
545
546 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA,
547 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
548 EXPECT_EQ(opinion.at("FIRST").permitSync, true);
549 EXPECT_EQ(opinion.at("FIRST").checkOnReceive, false);
550 EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false);
551 }
552
553 /**
554 * @tc.name: RelationalSchemaCompareTest002
555 * @tc.desc: Test relational schema v2.1 negotiate with same schema string
556 * @tc.type: FUNC
557 * @tc.require:
558 * @tc.author: lianhuix
559 */
560 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest002, TestSize.Level1)
561 {
562 RelationalSchemaObject schemaObj;
563 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
564 EXPECT_EQ(errCode, E_OK);
565
566 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
567 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
568 EXPECT_EQ(opinion.at("FIRST").permitSync, true);
569 EXPECT_EQ(opinion.at("FIRST").checkOnReceive, false);
570 EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false);
571 }
572
573 /**
574 * @tc.name: RelationalSchemaCompareTest003
575 * @tc.desc: Test relational schema v2.1 negotiate with schema v2.0
576 * @tc.type: FUNC
577 * @tc.require:
578 * @tc.author: lianhuix
579 */
580 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest003, TestSize.Level1)
581 {
582 RelationalSchemaObject schemaObj;
583 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
584 EXPECT_EQ(errCode, E_OK);
585
586 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA,
587 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
588 EXPECT_TRUE(opinion.empty());
589 }
590
591 /**
592 * @tc.name: RelationalSchemaCompareTest004
593 * @tc.desc: Test relational schema v2.0 negotiate with schema v2.1
594 * @tc.type: FUNC
595 * @tc.require:
596 * @tc.author: lianhuix
597 */
598 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest004, TestSize.Level1)
599 {
600 RelationalSchemaObject schemaObj;
601 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
602 EXPECT_EQ(errCode, E_OK);
603
604 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
605 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
606 EXPECT_TRUE(opinion.empty());
607 }
608
609 /**
610 * @tc.name: RelationalSchemaCompareTest005
611 * @tc.desc: Test collaboration relational schema negotiate with other table mode
612 * @tc.type: FUNC
613 * @tc.require:
614 * @tc.author: lianhuix
615 */
616 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest005, TestSize.Level1)
617 {
618 RelationalSchemaObject schemaObj;
619 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1);
620 EXPECT_EQ(errCode, E_OK);
621 schemaObj.SetTableMode(DistributedTableMode::COLLABORATION);
622
623 RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1,
624 static_cast<uint8_t>(SchemaType::RELATIVE), SOFTWARE_VERSION_CURRENT);
625 EXPECT_TRUE(opinion.empty());
626 }
627
628 /**
629 * @tc.name: RelationalTableCompareTest001
630 * @tc.desc: Test relational schema negotiate with same schema string
631 * @tc.type: FUNC
632 * @tc.require:
633 * @tc.author: lianhuix
634 */
635 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalTableCompareTest001, TestSize.Level1)
636 {
637 RelationalSchemaObject schemaObj;
638 int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA);
639 EXPECT_EQ(errCode, E_OK);
640 TableInfo table1 = schemaObj.GetTable("FIRST");
641 TableInfo table2 = schemaObj.GetTable("FIRST");
642 EXPECT_EQ(table1.CompareWithTable(table2), -E_RELATIONAL_TABLE_EQUAL);
643
644 table2.AddIndexDefine("indexname", {"field_name2", "field_name1"});
645 EXPECT_EQ(table1.CompareWithTable(table2), -E_RELATIONAL_TABLE_COMPATIBLE);
646
647 TableInfo table3 = schemaObj.GetTable("SECOND");
648 EXPECT_EQ(table1.CompareWithTable(table3), -E_RELATIONAL_TABLE_INCOMPATIBLE);
649
650 TableInfo table4 = schemaObj.GetTable("FIRST");
651 table4.AddField(table3.GetFields().at("value"));
652 EXPECT_EQ(table1.CompareWithTable(table4), -E_RELATIONAL_TABLE_COMPATIBLE_UPGRADE);
653
654 TableInfo table5 = schemaObj.GetTable("FIRST");
655 table5.AddField(table3.GetFields().at("key"));
656 EXPECT_EQ(table1.CompareWithTable(table5), -E_RELATIONAL_TABLE_INCOMPATIBLE);
657
658 TableInfo table6 = schemaObj.GetTable("FIRST");
659 table6.SetUniqueDefine({{"field_name1", "field_name1"}});
660 EXPECT_EQ(table1.CompareWithTable(table6, SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1),
661 -E_RELATIONAL_TABLE_INCOMPATIBLE);
662
663 TableInfo table7 = schemaObj.GetTable("FIRST");
664 table7.SetAutoIncrement(false);
665 EXPECT_EQ(table1.CompareWithTable(table7, SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1),
666 -E_RELATIONAL_TABLE_INCOMPATIBLE);
667 }
668
669 /**
670 * @tc.name: RelationalSchemaOpinionTest001
671 * @tc.desc: Test relational schema sync opinion
672 * @tc.type: FUNC
673 * @tc.require:
674 * @tc.author: lianhuix
675 */
676 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaOpinionTest001, TestSize.Level1)
677 {
678 RelationalSyncOpinion opinion;
679 opinion["table_1"] = SyncOpinion {true, false, false};
680 opinion["table_2"] = SyncOpinion {false, true, false};
681 opinion["table_3"] = SyncOpinion {false, false, true};
682
683 uint32_t len = SchemaNegotiate::CalculateParcelLen(opinion);
684 std::vector<uint8_t> buff(len, 0);
685 Parcel writeParcel(buff.data(), len);
686 int errCode = SchemaNegotiate::SerializeData(opinion, writeParcel);
687 EXPECT_EQ(errCode, E_OK);
688
689 Parcel readParcel(buff.data(), len);
690 RelationalSyncOpinion opinionRecv;
691 errCode = SchemaNegotiate::DeserializeData(readParcel, opinionRecv);
692 EXPECT_EQ(errCode, E_OK);
693
694 EXPECT_EQ(opinion.size(), opinionRecv.size());
695 for (const auto &it : opinion) {
696 SyncOpinion tableOpinionRecv = opinionRecv.at(it.first);
697 EXPECT_EQ(it.second.permitSync, tableOpinionRecv.permitSync);
698 EXPECT_EQ(it.second.requirePeerConvert, tableOpinionRecv.requirePeerConvert);
699 }
700 }
701
702 /**
703 * @tc.name: RelationalSchemaNegotiateTest001
704 * @tc.desc: Test relational schema negotiate
705 * @tc.type: FUNC
706 * @tc.require:
707 * @tc.author: lianhuix
708 */
709 HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaNegotiateTest001, TestSize.Level1)
710 {
711 RelationalSyncOpinion localOpinion;
712 localOpinion["table_1"] = SyncOpinion {true, false, false};
713 localOpinion["table_2"] = SyncOpinion {false, true, false};
714 localOpinion["table_3"] = SyncOpinion {false, false, true};
715
716 RelationalSyncOpinion remoteOpinion;
717 remoteOpinion["table_2"] = SyncOpinion {true, false, false};
718 remoteOpinion["table_3"] = SyncOpinion {false, true, false};
719 remoteOpinion["table_4"] = SyncOpinion {false, false, true};
720 RelationalSyncStrategy strategy = SchemaNegotiate::ConcludeSyncStrategy(localOpinion, remoteOpinion);
721
722 EXPECT_EQ(strategy.size(), 2u);
723 EXPECT_EQ(strategy.at("table_2").permitSync, true);
724 EXPECT_EQ(strategy.at("table_3").permitSync, false);
725 }
726
727 /**
728 * @tc.name: TableCompareTest001
729 * @tc.desc: Test table compare
730 * @tc.type: FUNC
731 * @tc.require:
732 * @tc.author: lianhuix
733 */
734 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableCompareTest001, TestSize.Level1)
735 {
736 FieldInfo field1;
737 field1.SetFieldName("a");
738 FieldInfo field2;
739 field2.SetFieldName("b");
740 FieldInfo field3;
741 field3.SetFieldName("c");
742 FieldInfo field4;
743 field4.SetFieldName("d");
744
745 TableInfo table;
746 table.AddField(field2);
747 table.AddField(field3);
748
749 TableInfo inTable1;
750 inTable1.AddField(field1);
751 inTable1.AddField(field2);
752 inTable1.AddField(field3);
753 EXPECT_EQ(table.CompareWithTable(inTable1), -E_RELATIONAL_TABLE_COMPATIBLE_UPGRADE);
754
755 TableInfo inTable2;
756 inTable2.AddField(field1);
757 inTable2.AddField(field2);
758 inTable2.AddField(field4);
759 EXPECT_EQ(table.CompareWithTable(inTable2), -E_RELATIONAL_TABLE_INCOMPATIBLE);
760
761 TableInfo inTable3;
762 inTable3.AddField(field3);
763 inTable3.AddField(field2);
764 EXPECT_EQ(table.CompareWithTable(inTable3), -E_RELATIONAL_TABLE_EQUAL);
765 }
766
767 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableCaseInsensitiveCompareTest001, TestSize.Level1)
768 {
769 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
770 EXPECT_NE(db, nullptr);
771 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
772 std::string createStudentSql = "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT, score INT, level INT)";
773 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createStudentSql), SQLITE_OK);
774
775 TableInfo tableStudent;
776 EXPECT_EQ(SQLiteUtils::AnalysisSchema(db, "STUDENT", tableStudent), E_OK);
777
778 RelationalSchemaObject schema;
779 schema.AddRelationalTable(tableStudent);
780
781 EXPECT_FALSE(schema.GetTable("STUDENT").Empty());
782 EXPECT_FALSE(schema.GetTable("StudENT").Empty());
783 EXPECT_EQ(schema.GetTable("StudENT").CompareWithTable(schema.GetTable("STUDENT")), -E_RELATIONAL_TABLE_EQUAL);
784
785 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
786 }
787
788 namespace {
GetTableInfo(sqlite3 * db,const std::string & tableName,const std::string & sql)789 TableInfo GetTableInfo(sqlite3 *db, const std::string &tableName, const std::string &sql)
790 {
791 EXPECT_NE(db, nullptr);
792 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK);
793 TableInfo tableInfo;
794 EXPECT_EQ(SQLiteUtils::AnalysisSchema(db, tableName, tableInfo), E_OK);
795 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS " + tableName), SQLITE_OK);
796 return tableInfo;
797 }
798 }
799
800 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableCaseInsensitiveCompareTest002, TestSize.Level1)
801 {
802 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
803 EXPECT_NE(db, nullptr);
804 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
805
806 std::string createTableSql1 = "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT, score INT, level INT); " \
807 "create index index_name on student (name);";
808 TableInfo table1 = GetTableInfo(db, "student", createTableSql1);
809 std::string createTableSql2 = "CREATE TABLE Student(ID INTEGER PRIMARY KEY, Name TEXT, Score INT, Level INT); " \
810 "create index index_NAME on student (Name);";
811 TableInfo table2 = GetTableInfo(db, "Student", createTableSql2);
812
813 EXPECT_EQ(table1.CompareWithTable(table2), -E_RELATIONAL_TABLE_EQUAL);
814
815 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
816 db = nullptr;
817 }
818
819 namespace {
TableCompareTest(sqlite3 * db,const std::string & sql1,const std::string & sql2)820 int TableCompareTest(sqlite3 *db, const std::string &sql1, const std::string &sql2)
821 {
822 RelationalTestUtils::ExecSql(db, sql1);
823 TableInfo table1;
824 SQLiteUtils::AnalysisSchema(db, "student", table1);
825 RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student");
826 RelationalTestUtils::ExecSql(db, sql2);
827 TableInfo table2;
828 SQLiteUtils::AnalysisSchema(db, "student", table2);
829 RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student");
830 return table1.CompareWithTable(table2);
831 }
832
833 /**
834 * @tc.name: TableCompareTest001
835 * @tc.desc: Test table compare with default value
836 * @tc.type: FUNC
837 * @tc.require:
838 * @tc.author: lianhuix
839 */
840 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableCompareTest002, TestSize.Level1)
841 {
842 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
843 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
844 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)"),
845 -E_RELATIONAL_TABLE_EQUAL);
846 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
847 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'xue')"),
848 -E_RELATIONAL_TABLE_INCOMPATIBLE);
849 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
850 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT '')"),
851 -E_RELATIONAL_TABLE_INCOMPATIBLE);
852 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
853 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'NULL')"),
854 -E_RELATIONAL_TABLE_INCOMPATIBLE);
855 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
856 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'null')"),
857 -E_RELATIONAL_TABLE_INCOMPATIBLE);
858 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
859 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT NULL)"),
860 -E_RELATIONAL_TABLE_INCOMPATIBLE);
861 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT)",
862 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT null)"),
863 -E_RELATIONAL_TABLE_INCOMPATIBLE);
864 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'XUE')",
865 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'xue')"),
866 -E_RELATIONAL_TABLE_INCOMPATIBLE);
867 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT NULL)",
868 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT null)"),
869 -E_RELATIONAL_TABLE_EQUAL);
870 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'NULL')",
871 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT 'null')"),
872 -E_RELATIONAL_TABLE_INCOMPATIBLE);
873 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT '')",
874 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT NULL)"),
875 -E_RELATIONAL_TABLE_INCOMPATIBLE);
876 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT '')",
877 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT null)"),
878 -E_RELATIONAL_TABLE_INCOMPATIBLE);
879 EXPECT_EQ(TableCompareTest(db, "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT '')",
880 "CREATE TABLE student(id INTEGER PRIMARY KEY, name TEXT DEFAULT '')"),
881 -E_RELATIONAL_TABLE_EQUAL);
882 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
883 db = nullptr;
884 }
885 } // namespace
886
887 /**
888 * @tc.name: FieldInfoCompareTest
889 * @tc.desc: Test field info compare
890 * @tc.type: FUNC
891 * @tc.require:
892 * @tc.author: suyue
893 */
894 HWTEST_F(DistributedDBRelationalSchemaObjectTest, FieldInfoCompareTest, TestSize.Level1)
895 {
896 /**
897 * @tc.steps: step1. call CompareWithField when storageType is different
898 * @tc.expected: step1. return false.
899 */
900 FieldInfo field1;
901 field1.SetStorageType(StorageType::STORAGE_TYPE_INTEGER);
902 FieldInfo field2;
903 EXPECT_EQ(field2.CompareWithField(field1, true), false);
904
905 /**
906 * @tc.steps: step2. call CompareWithField when fieldName is different
907 * @tc.expected: step2. return false.
908 */
909 field1.SetFieldName("test1");
910 field1.SetFieldName("test2");
911 EXPECT_EQ(field2.CompareWithField(field1, true), false);
912 }
913
914 /**
915 * @tc.name: TableInfoInterfacesTest
916 * @tc.desc: Test TableInfo Interfaces
917 * @tc.type: FUNC
918 * @tc.require:
919 * @tc.author: suyue
920 */
921 HWTEST_F(DistributedDBRelationalSchemaObjectTest, TableInfoInterfacesTest, TestSize.Level1)
922 {
923 /**
924 * @tc.steps: step1. GetFieldName with empty TableInfo class
925 * @tc.expected: step1. return empty string.
926 */
927 TableInfo table1;
928 std::string str1 = table1.GetFieldName(0);
929 const std::string expectStr1 = "";
930 EXPECT_TRUE(str1.compare(0, expectStr1.length(), expectStr1) == 0);
931 table1.ToTableInfoString("");
932
933 /**
934 * @tc.steps: step2. Set and get tableId.
935 * @tc.expected: step2. success.
936 */
937 int inputId = 1;
938 table1.SetTableId(inputId);
939 int outputId = table1.GetTableId();
940 EXPECT_EQ(outputId, inputId);
941 }
942
943 /**
944 * @tc.name: SchemaTableCompareTest
945 * @tc.desc: Test LiteSchemaTable Compare
946 * @tc.type: FUNC
947 * @tc.require:
948 * @tc.author: suyue
949 */
950 HWTEST_F(DistributedDBRelationalSchemaObjectTest, SchemaTableCompareTest, TestSize.Level1)
951 {
952 /**
953 * @tc.steps: step1. Set key index of SetPrimaryKey to an invalid value
954 * @tc.expected: step1. fieldName vector is null.
955 */
956 TableInfo table1;
957 int keyIndex = -1;
958 table1.SetPrimaryKey("test", keyIndex);
959 CompositeFields vec = table1.GetIdentifyKey();
960 uint32_t expectedVal = 0;
961 EXPECT_EQ(vec.size(), expectedVal);
962
963 /**
964 * @tc.steps: step2. Compare table when fieldName of SetPrimaryKey is set to'rowid'
965 * @tc.expected: step2. compare return -E_RELATIONAL_TABLE_INCOMPATIBLE.
966 */
967 const std::vector<CompositeFields> uniqueDefine = {{"test0", "test1"}};
968 table1.SetUniqueDefine(uniqueDefine);
969 const std::map<int, FieldName> keyName1 = {{0, "rowid"}};
970 table1.SetPrimaryKey(keyName1);
971
972 vec = table1.GetIdentifyKey();
973 EXPECT_EQ(vec.size(), uniqueDefine[0].size());
974 int ret = table1.CompareWithLiteSchemaTable(table1);
975 EXPECT_EQ(ret, -E_RELATIONAL_TABLE_INCOMPATIBLE);
976
977 /**
978 * @tc.steps: step3. Compare table when fieldName of SetPrimaryKey is not set to "rowid".
979 * @tc.expected: step3. compare return E_OK.
980 */
981 FieldInfo field1;
982 table1.AddField(field1);
983 const std::map<int, FieldName> keyName2 = {{0, "test0"}, {1, "test1"}};
984 table1.SetPrimaryKey(keyName2);
985
986 vec = table1.GetIdentifyKey();
987 EXPECT_EQ(vec.size(), keyName2.size());
988 field1.SetFieldName("test1");
989 ret = table1.CompareWithLiteSchemaTable(table1);
990 EXPECT_EQ(ret, E_OK);
991 }
992 #endif