• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef RELATIONAL_STORE
16 #include "relational_schema_object.h"
17 
18 #include <algorithm>
19 
20 #include "db_common.h"
21 #include "json_object.h"
22 #include "schema_constant.h"
23 #include "schema_utils.h"
24 
25 namespace DistributedDB {
IsSchemaValid() const26 bool RelationalSchemaObject::IsSchemaValid() const
27 {
28     return isValid_;
29 }
30 
GetSchemaType() const31 SchemaType RelationalSchemaObject::GetSchemaType() const
32 {
33     return schemaType_;
34 }
35 
ToSchemaString() const36 std::string RelationalSchemaObject::ToSchemaString() const
37 {
38     return schemaString_;
39 }
40 
ParseFromSchemaString(const std::string & inSchemaString)41 int RelationalSchemaObject::ParseFromSchemaString(const std::string &inSchemaString)
42 {
43     if (isValid_) {
44         return -E_NOT_PERMIT;
45     }
46 
47     if (inSchemaString.empty() || inSchemaString.size() > SchemaConstant::SCHEMA_STRING_SIZE_LIMIT) {
48         LOGE("[RelationalSchema][Parse] SchemaSize=%zu is invalid.", inSchemaString.size());
49         return -E_INVALID_ARGS;
50     }
51     JsonObject schemaObj;
52     int errCode = schemaObj.Parse(inSchemaString);
53     if (errCode != E_OK) {
54         LOGE("[RelationalSchema][Parse] Schema json string parse failed: %d.", errCode);
55         return errCode;
56     }
57 
58     errCode = ParseRelationalSchema(schemaObj);
59     if (errCode != E_OK) {
60         LOGE("[RelationalSchema][Parse] Parse to relational schema failed: %d.", errCode);
61         return errCode;
62     }
63 
64     schemaType_ = SchemaType::RELATIVE;
65     schemaString_ = schemaObj.ToString();
66     isValid_ = true;
67     return E_OK;
68 }
69 
GenerateSchemaString()70 void RelationalSchemaObject::GenerateSchemaString()
71 {
72     schemaString_ = {};
73     schemaString_ += "{";
74     schemaString_ += R"("SCHEMA_VERSION":")" + schemaVersion_ + R"(",)";
75     schemaString_ += R"("SCHEMA_TYPE":"RELATIVE",)";
76     if (schemaVersion_ == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1) {
77         std::string modeString = tableMode_ == DistributedTableMode::COLLABORATION ?
78             SchemaConstant::KEYWORD_TABLE_COLLABORATION : SchemaConstant::KEYWORD_TABLE_SPLIT_DEVICE;
79         schemaString_ += R"("TABLE_MODE":")" + modeString + R"(",)";
80     }
81     schemaString_ += R"("TABLES":[)";
82     for (auto it = tables_.begin(); it != tables_.end(); it++) {
83         if (it != tables_.begin()) {
84             schemaString_ += ",";
85         }
86         schemaString_ += it->second.ToTableInfoString(schemaVersion_);
87     }
88     schemaString_ += R"(])";
89     schemaString_ += "}";
90 }
91 
AddRelationalTable(const TableInfo & table)92 void RelationalSchemaObject::AddRelationalTable(const TableInfo &table)
93 {
94     tables_[table.GetTableName()] = table;
95     isValid_ = true;
96     if (table.GetPrimaryKey().size() > 1) { // Table with composite primary keys
97         // Composite primary keys are supported since version 2.1
98         schemaVersion_ = SchemaConstant::SCHEMA_CURRENT_VERSION;
99     }
100     GenerateSchemaString();
101 }
102 
RemoveRelationalTable(const std::string & tableName)103 void RelationalSchemaObject::RemoveRelationalTable(const std::string &tableName)
104 {
105     tables_.erase(tableName);
106     GenerateSchemaString();
107 }
108 
GetTables() const109 const TableInfoMap &RelationalSchemaObject::GetTables() const
110 {
111     return tables_;
112 }
113 
GetTableNames() const114 std::vector<std::string> RelationalSchemaObject::GetTableNames() const
115 {
116     std::vector<std::string> tableNames;
117     for (const auto &it : tables_) {
118         tableNames.emplace_back(it.first);
119     }
120     return tableNames;
121 }
122 
GetTable(const std::string & tableName) const123 TableInfo RelationalSchemaObject::GetTable(const std::string &tableName) const
124 {
125     auto it = tables_.find(tableName);
126     if (it != tables_.end()) {
127         return it->second;
128     }
129     return {};
130 }
131 
GetSchemaVersion() const132 std::string RelationalSchemaObject::GetSchemaVersion() const
133 {
134     return schemaVersion_;
135 }
136 
GetTableMode() const137 DistributedTableMode RelationalSchemaObject::GetTableMode() const
138 {
139     return tableMode_;
140 }
141 
SetTableMode(DistributedTableMode mode)142 void RelationalSchemaObject::SetTableMode(DistributedTableMode mode)
143 {
144     tableMode_ = mode;
145     if (tableMode_ == DistributedTableMode::COLLABORATION) {
146         schemaVersion_ = SchemaConstant::SCHEMA_CURRENT_VERSION;
147     }
148     GenerateSchemaString();
149 }
150 
CompareAgainstSchemaObject(const std::string & inSchemaString,std::map<std::string,int> & cmpRst) const151 int RelationalSchemaObject::CompareAgainstSchemaObject(const std::string &inSchemaString,
152     std::map<std::string, int> &cmpRst) const
153 {
154     return E_OK;
155 }
156 
CompareAgainstSchemaObject(const RelationalSchemaObject & inSchemaObject,std::map<std::string,int> & cmpRst) const157 int RelationalSchemaObject::CompareAgainstSchemaObject(const RelationalSchemaObject &inSchemaObject,
158     std::map<std::string, int> &cmpRst) const
159 {
160     return E_OK;
161 }
162 
163 namespace {
GetMemberFromJsonObject(const JsonObject & inJsonObject,const std::string & fieldName,FieldType expectType,bool isNecessary,FieldValue & fieldValue)164 int GetMemberFromJsonObject(const JsonObject &inJsonObject, const std::string &fieldName, FieldType expectType,
165     bool isNecessary, FieldValue &fieldValue)
166 {
167     if (!inJsonObject.IsFieldPathExist(FieldPath {fieldName})) {
168         if (isNecessary) {
169             LOGE("[RelationalSchema][Parse] Get schema %s not exist. isNecessary: %d", fieldName.c_str(), isNecessary);
170             return -E_SCHEMA_PARSE_FAIL;
171         }
172         return -E_NOT_FOUND;
173     }
174 
175     FieldType fieldType;
176     int errCode = inJsonObject.GetFieldTypeByFieldPath(FieldPath {fieldName}, fieldType);
177     if (errCode != E_OK) {
178         LOGE("[RelationalSchema][Parse] Get schema %s fieldType failed: %d.", fieldName.c_str(), errCode);
179         return -E_SCHEMA_PARSE_FAIL;
180     }
181 
182     if (fieldType != expectType) {
183         LOGE("[RelationalSchema][Parse] Expect %s fieldType %d but: %d.", fieldName.c_str(),
184             static_cast<int>(expectType), static_cast<int>(fieldType));
185         return -E_SCHEMA_PARSE_FAIL;
186     }
187 
188     errCode = inJsonObject.GetFieldValueByFieldPath(FieldPath {fieldName}, fieldValue);
189     if (errCode != E_OK) {
190         LOGE("[RelationalSchema][Parse] Get schema %s value failed: %d.", fieldName.c_str(), errCode);
191         return -E_SCHEMA_PARSE_FAIL;
192     }
193     return E_OK;
194 }
195 }
196 
ParseRelationalSchema(const JsonObject & inJsonObject)197 int RelationalSchemaObject::ParseRelationalSchema(const JsonObject &inJsonObject)
198 {
199     int errCode = ParseCheckSchemaVersion(inJsonObject);
200     if (errCode != E_OK) {
201         return errCode;
202     }
203     errCode = ParseCheckSchemaType(inJsonObject);
204     if (errCode != E_OK) {
205         return errCode;
206     }
207     errCode = ParseCheckTableMode(inJsonObject);
208     if (errCode != E_OK) {
209         return errCode;
210     }
211     return ParseCheckSchemaTableDefine(inJsonObject);
212 }
213 
214 namespace {
IsSchemaVersionValid(const std::string & version)215 inline bool IsSchemaVersionValid(const std::string &version)
216 {
217     std::string stripedVersion = SchemaUtils::Strip(version);
218     return stripedVersion == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2 ||
219         stripedVersion == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1;
220 }
221 }
222 
ParseCheckSchemaVersion(const JsonObject & inJsonObject)223 int RelationalSchemaObject::ParseCheckSchemaVersion(const JsonObject &inJsonObject)
224 {
225     FieldValue fieldValue;
226     int errCode = GetMemberFromJsonObject(inJsonObject, SchemaConstant::KEYWORD_SCHEMA_VERSION,
227         FieldType::LEAF_FIELD_STRING, true, fieldValue);
228     if (errCode != E_OK) {
229         return errCode;
230     }
231 
232     if (IsSchemaVersionValid(fieldValue.stringValue)) {
233         schemaVersion_ = fieldValue.stringValue;
234         return E_OK;
235     }
236 
237     LOGE("[RelationalSchema][Parse] Unexpected SCHEMA_VERSION=%s.", fieldValue.stringValue.c_str());
238     return -E_SCHEMA_PARSE_FAIL;
239 }
240 
ParseCheckSchemaType(const JsonObject & inJsonObject)241 int RelationalSchemaObject::ParseCheckSchemaType(const JsonObject &inJsonObject)
242 {
243     FieldValue fieldValue;
244     int errCode = GetMemberFromJsonObject(inJsonObject, SchemaConstant::KEYWORD_SCHEMA_TYPE,
245         FieldType::LEAF_FIELD_STRING, true, fieldValue);
246     if (errCode != E_OK) {
247         return errCode;
248     }
249 
250     if (SchemaUtils::Strip(fieldValue.stringValue) != SchemaConstant::KEYWORD_TYPE_RELATIVE) {
251         LOGE("[RelationalSchema][Parse] Unexpected SCHEMA_TYPE=%s.", fieldValue.stringValue.c_str());
252         return -E_SCHEMA_PARSE_FAIL;
253     }
254     schemaType_ = SchemaType::RELATIVE;
255     return E_OK;
256 }
257 
258 namespace {
IsTableModeValid(const std::string & mode)259 inline bool IsTableModeValid(const std::string &mode)
260 {
261     std::string stripedMode = SchemaUtils::Strip(mode);
262     return stripedMode == SchemaConstant::KEYWORD_TABLE_SPLIT_DEVICE ||
263         stripedMode == SchemaConstant::KEYWORD_TABLE_COLLABORATION;
264 }
265 }
266 
ParseCheckTableMode(const JsonObject & inJsonObject)267 int RelationalSchemaObject::ParseCheckTableMode(const JsonObject &inJsonObject)
268 {
269     if (schemaVersion_ == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2) {
270         return E_OK; // version 2 has no table mode, no parsing required
271     }
272 
273     FieldValue fieldValue;
274     int errCode = GetMemberFromJsonObject(inJsonObject, SchemaConstant::KEYWORD_TABLE_MODE,
275         FieldType::LEAF_FIELD_STRING, true, fieldValue);
276     if (errCode != E_OK) {
277         return errCode;
278     }
279 
280     if (!IsTableModeValid(fieldValue.stringValue)) {
281         LOGE("[RelationalSchema][Parse] Unexpected TABLE_MODE=%s.", fieldValue.stringValue.c_str());
282         return -E_SCHEMA_PARSE_FAIL;
283     }
284 
285     tableMode_ = SchemaUtils::Strip(fieldValue.stringValue) == SchemaConstant::KEYWORD_TABLE_SPLIT_DEVICE ?
286         DistributedDB::SPLIT_BY_DEVICE : DistributedTableMode::COLLABORATION;
287     return E_OK;
288 }
289 
ParseCheckSchemaTableDefine(const JsonObject & inJsonObject)290 int RelationalSchemaObject::ParseCheckSchemaTableDefine(const JsonObject &inJsonObject)
291 {
292     FieldType fieldType;
293     int errCode = inJsonObject.GetFieldTypeByFieldPath(FieldPath {SchemaConstant::KEYWORD_SCHEMA_TABLE}, fieldType);
294     if (errCode != E_OK) {
295         LOGE("[RelationalSchema][Parse] Get schema TABLES fieldType failed: %d.", errCode);
296         return -E_SCHEMA_PARSE_FAIL;
297     }
298     if (FieldType::LEAF_FIELD_ARRAY != fieldType) {
299         LOGE("[RelationalSchema][Parse] Expect TABLES fieldType ARRAY but %s.",
300             SchemaUtils::FieldTypeString(fieldType).c_str());
301         return -E_SCHEMA_PARSE_FAIL;
302     }
303     std::vector<JsonObject> tables;
304     errCode = inJsonObject.GetObjectArrayByFieldPath(FieldPath{SchemaConstant::KEYWORD_SCHEMA_TABLE}, tables);
305     if (errCode != E_OK) {
306         LOGE("[RelationalSchema][Parse] Get schema TABLES value failed: %d.", errCode);
307         return -E_SCHEMA_PARSE_FAIL;
308     }
309     for (const JsonObject &table : tables) {
310         errCode = ParseCheckTableInfo(table);
311         if (errCode != E_OK) {
312             LOGE("[RelationalSchema][Parse] Parse schema TABLES failed: %d.", errCode);
313             return -E_SCHEMA_PARSE_FAIL;
314         }
315     }
316     return E_OK;
317 }
318 
ParseCheckTableInfo(const JsonObject & inJsonObject)319 int RelationalSchemaObject::ParseCheckTableInfo(const JsonObject &inJsonObject)
320 {
321     TableInfo resultTable;
322     int errCode = ParseCheckTableName(inJsonObject, resultTable);
323     if (errCode != E_OK) {
324         return errCode;
325     }
326     errCode = ParseCheckTableDefine(inJsonObject, resultTable);
327     if (errCode != E_OK) {
328         return errCode;
329     }
330     errCode = ParseCheckTableAutoInc(inJsonObject, resultTable);
331     if (errCode != E_OK) {
332         return errCode;
333     }
334     errCode = ParseCheckTablePrimaryKey(inJsonObject, resultTable);
335     if (errCode != E_OK) {
336         return errCode;
337     }
338 
339     errCode = ParseCheckTableSyncType(inJsonObject, resultTable);
340     if (errCode != E_OK) {
341         return errCode;
342     }
343     errCode = ParseCheckTableIndex(inJsonObject, resultTable);
344     if (errCode != E_OK) {
345         return errCode;
346     }
347     errCode = ParseCheckTableUnique(inJsonObject, resultTable);
348     if (errCode != E_OK) {
349         return errCode;
350     }
351     tables_[resultTable.GetTableName()] = resultTable;
352     return E_OK;
353 }
354 
ParseCheckTableName(const JsonObject & inJsonObject,TableInfo & resultTable)355 int RelationalSchemaObject::ParseCheckTableName(const JsonObject &inJsonObject, TableInfo &resultTable)
356 {
357     FieldValue fieldValue;
358     int errCode = GetMemberFromJsonObject(inJsonObject, "NAME", FieldType::LEAF_FIELD_STRING,
359         true, fieldValue);
360     if (errCode == E_OK) {
361         if (!DBCommon::CheckIsAlnumAndUnderscore(fieldValue.stringValue)) {
362             LOGE("[RelationalSchema][Parse] Invalid characters in table name, err=%d.", errCode);
363             return -E_SCHEMA_PARSE_FAIL;
364         }
365         resultTable.SetTableName(fieldValue.stringValue);
366     }
367     return errCode;
368 }
369 
ParseCheckTableDefine(const JsonObject & inJsonObject,TableInfo & resultTable)370 int RelationalSchemaObject::ParseCheckTableDefine(const JsonObject &inJsonObject, TableInfo &resultTable)
371 {
372     std::map<FieldPath, FieldType> tableFields;
373     int errCode = inJsonObject.GetSubFieldPathAndType(FieldPath {"DEFINE"}, tableFields);
374     if (errCode != E_OK) {
375         LOGE("[RelationalSchema][Parse] Get schema TABLES DEFINE failed: %d.", errCode);
376         return -E_SCHEMA_PARSE_FAIL;
377     }
378 
379     for (const auto &field : tableFields) {
380         if (field.second != FieldType::INTERNAL_FIELD_OBJECT) {
381             LOGE("[RelationalSchema][Parse] Expect schema TABLES DEFINE fieldType INTERNAL OBJECT but : %s.",
382                 SchemaUtils::FieldTypeString(field.second).c_str());
383             return -E_SCHEMA_PARSE_FAIL;
384         }
385 
386         JsonObject fieldObj;
387         errCode = inJsonObject.GetObjectByFieldPath(field.first, fieldObj);
388         if (errCode != E_OK) {
389             LOGE("[RelationalSchema][Parse] Get table field object failed. %d", errCode);
390             return errCode;
391         }
392 
393         if (!DBCommon::CheckIsAlnumAndUnderscore(field.first[1])) {
394             LOGE("[RelationalSchema][Parse] Invalid characters in field name, err=%d.", errCode);
395             return -E_SCHEMA_PARSE_FAIL;
396         }
397 
398         FieldInfo fieldInfo;
399         fieldInfo.SetFieldName(field.first[1]); // 1 : table name element in path
400         errCode = ParseCheckTableFieldInfo(fieldObj, field.first, fieldInfo);
401         if (errCode != E_OK) {
402             LOGE("[RelationalSchema][Parse] Parse table field info failed. %d", errCode);
403             return -E_SCHEMA_PARSE_FAIL;
404         }
405         resultTable.AddField(fieldInfo);
406     }
407     return E_OK;
408 }
409 
ParseCheckTableFieldInfo(const JsonObject & inJsonObject,const FieldPath & path,FieldInfo & field)410 int RelationalSchemaObject::ParseCheckTableFieldInfo(const JsonObject &inJsonObject, const FieldPath &path,
411     FieldInfo &field)
412 {
413     FieldValue fieldValue;
414     int errCode = GetMemberFromJsonObject(inJsonObject, "COLUMN_ID", FieldType::LEAF_FIELD_INTEGER, true, fieldValue);
415     if (errCode != E_OK) {
416         return errCode;
417     }
418     field.SetColumnId(fieldValue.integerValue);
419 
420     errCode = GetMemberFromJsonObject(inJsonObject, "TYPE", FieldType::LEAF_FIELD_STRING, true, fieldValue);
421     if (errCode != E_OK) {
422         return errCode;
423     }
424     field.SetDataType(fieldValue.stringValue);
425 
426     errCode = GetMemberFromJsonObject(inJsonObject, "NOT_NULL", FieldType::LEAF_FIELD_BOOL, true, fieldValue);
427     if (errCode != E_OK) {
428         return errCode;
429     }
430     field.SetNotNull(fieldValue.boolValue);
431 
432     errCode = GetMemberFromJsonObject(inJsonObject, "DEFAULT", FieldType::LEAF_FIELD_STRING, false, fieldValue);
433     if (errCode == E_OK) {
434         field.SetDefaultValue(fieldValue.stringValue);
435     } else if (errCode != -E_NOT_FOUND) {
436         return errCode;
437     }
438 
439     return E_OK;
440 }
441 
ParseCheckTableAutoInc(const JsonObject & inJsonObject,TableInfo & resultTable)442 int RelationalSchemaObject::ParseCheckTableAutoInc(const JsonObject &inJsonObject, TableInfo &resultTable)
443 {
444     FieldValue fieldValue;
445     int errCode = GetMemberFromJsonObject(inJsonObject, "AUTOINCREMENT", FieldType::LEAF_FIELD_BOOL, false, fieldValue);
446     if (errCode == E_OK) {
447         resultTable.SetAutoIncrement(fieldValue.boolValue);
448     } else if (errCode != -E_NOT_FOUND) {
449         return errCode;
450     }
451     return E_OK;
452 }
453 
ParseCheckTablePrimaryKey(const JsonObject & inJsonObject,TableInfo & resultTable)454 int RelationalSchemaObject::ParseCheckTablePrimaryKey(const JsonObject &inJsonObject, TableInfo &resultTable)
455 {
456     if (!inJsonObject.IsFieldPathExist(FieldPath {"PRIMARY_KEY"})) {
457         return E_OK;
458     }
459 
460     FieldType type;
461     int errCode = inJsonObject.GetFieldTypeByFieldPath(FieldPath {"PRIMARY_KEY"}, type);
462     if (errCode != E_OK) {
463         return errCode;
464     }
465 
466     if (type == FieldType::LEAF_FIELD_STRING) { // Compatible with schema 2.0
467         FieldValue fieldValue;
468         errCode = GetMemberFromJsonObject(inJsonObject, "PRIMARY_KEY", FieldType::LEAF_FIELD_STRING, false, fieldValue);
469         if (errCode == E_OK) {
470             resultTable.SetPrimaryKey(fieldValue.stringValue, 1);
471         }
472     } else if (type == FieldType::LEAF_FIELD_ARRAY) {
473         CompositeFields multiPrimaryKey;
474         errCode = inJsonObject.GetStringArrayByFieldPath(FieldPath {"PRIMARY_KEY"}, multiPrimaryKey);
475         if (errCode == E_OK) {
476             int index = 1; // primary key index
477             for (const auto &item : multiPrimaryKey) {
478                 resultTable.SetPrimaryKey(item, index++);
479             }
480         }
481     } else {
482         errCode = -E_SCHEMA_PARSE_FAIL;
483     }
484     return errCode;
485 }
486 
ParseCheckTableSyncType(const JsonObject & inJsonObject,TableInfo & resultTable)487 int RelationalSchemaObject::ParseCheckTableSyncType(const JsonObject &inJsonObject, TableInfo &resultTable)
488 {
489     FieldValue fieldValue;
490     int errCode = GetMemberFromJsonObject(inJsonObject, "TABLE_SYNC_TYPE", FieldType::LEAF_FIELD_INTEGER,
491         false, fieldValue);
492     if (errCode == E_OK) {
493         resultTable.SetTableSyncType(static_cast<TableSyncType>(fieldValue.integerValue));
494     } else if (errCode != -E_NOT_FOUND) {
495         return errCode;
496     }
497     return E_OK; // if there is no "TABLE_SYNC_TYPE" filed, the table_sync_type is DEVICE_COOPERATION
498 }
499 
ParseCheckTableIndex(const JsonObject & inJsonObject,TableInfo & resultTable)500 int RelationalSchemaObject::ParseCheckTableIndex(const JsonObject &inJsonObject, TableInfo &resultTable)
501 {
502     if (!inJsonObject.IsFieldPathExist(FieldPath {"INDEX"})) { // INDEX is not necessary
503         return E_OK;
504     }
505     std::map<FieldPath, FieldType> tableFields;
506     int errCode = inJsonObject.GetSubFieldPathAndType(FieldPath {"INDEX"}, tableFields);
507     if (errCode != E_OK) {
508         LOGE("[RelationalSchema][Parse] Get schema TABLES INDEX failed: %d.", errCode);
509         return -E_SCHEMA_PARSE_FAIL;
510     }
511 
512     for (const auto &field : tableFields) {
513         if (field.second != FieldType::LEAF_FIELD_ARRAY) {
514             LOGE("[RelationalSchema][Parse] Expect schema TABLES INDEX fieldType ARRAY but : %s.",
515                 SchemaUtils::FieldTypeString(field.second).c_str());
516             return -E_SCHEMA_PARSE_FAIL;
517         }
518         CompositeFields indexDefine;
519         errCode = inJsonObject.GetStringArrayByFieldPath(field.first, indexDefine);
520         if (errCode != E_OK) {
521             LOGE("[RelationalSchema][Parse] Get schema TABLES INDEX field value failed: %d.", errCode);
522             return -E_SCHEMA_PARSE_FAIL;
523         }
524         resultTable.AddIndexDefine(field.first[1], indexDefine); // 1 : second element in path
525     }
526     return E_OK;
527 }
528 
ParseCheckTableUnique(const JsonObject & inJsonObject,TableInfo & resultTable)529 int RelationalSchemaObject::ParseCheckTableUnique(const JsonObject &inJsonObject, TableInfo &resultTable)
530 {
531     if (!inJsonObject.IsFieldPathExist(FieldPath {"UNIQUE"})) { // UNIQUE is not necessary
532         return E_OK;
533     }
534 
535     std::vector<CompositeFields> uniques;
536     int errCode = inJsonObject.GetArrayContentOfStringOrStringArray(FieldPath {"UNIQUE"}, uniques);
537     if (errCode != E_OK) {
538         LOGE("[RelationalSchema][Parse] Get schema TABLES UNIQUE failed: %d.", errCode);
539         return -E_SCHEMA_PARSE_FAIL;
540     }
541     resultTable.SetUniqueDefine(uniques);
542     return E_OK;
543 }
544 }
545 #endif