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 "QueryHelper" 16 #include "query_helper.h" 17 #include <regex> 18 #include <sstream> 19 #include "data_query.h" 20 #include "device_manager_adapter.h" 21 #include "kvstore_utils.h" 22 #include "log_print.h" 23 #include "types.h" 24 namespace OHOS::DistributedKv { 25 constexpr int QUERY_SKIP_SIZE = 1; 26 constexpr int QUERY_WORD_SIZE = 2; 27 constexpr int MAX_QUERY_LENGTH = 5 * 1024; // Max query string length 5k 28 constexpr int MAX_QUERY_COMPLEXITY = 500; // Max query complexity 500 29 bool QueryHelper::hasPrefixKey_ = false; 30 std::string QueryHelper::deviceId_; 31 StringToDbQuery(const std::string & query,bool & isSuccess)32 DistributedDB::Query QueryHelper::StringToDbQuery(const std::string &query, bool &isSuccess) 33 { 34 ZLOGI("query string length:%{public}zu", query.length()); 35 DBQuery dbQuery = DBQuery::Select(); 36 if (query.empty()) { 37 ZLOGD("Query string is empty."); 38 isSuccess = true; 39 return dbQuery; 40 } 41 if (query.size() > MAX_QUERY_LENGTH) { 42 ZLOGE("Query string is too long."); 43 isSuccess = false; 44 return dbQuery; 45 } 46 deviceId_.clear(); 47 hasPrefixKey_ = (query.find(DataQuery::KEY_PREFIX) != std::string::npos); 48 size_t pos = query.find_first_not_of(DataQuery::SPACE); 49 std::string inputTrim = (pos == std::string::npos) ? "" : query.substr(pos); 50 std::regex regex(" "); 51 // regex split string by space 52 std::vector<std::string> words(std::sregex_token_iterator(inputTrim.begin(), inputTrim.end(), regex, -1), 53 std::sregex_token_iterator()); 54 55 if (words.empty()) { 56 ZLOGE("not enough params."); 57 return dbQuery; 58 } 59 int pointer = 0; // Read pointer starts at 0 60 int end = words.size() - 1; // Read pointer ends at size - 1 61 // Counts how many keywords has been handled 62 for (int count = 0; pointer <= end && count <= MAX_QUERY_COMPLEXITY; ++count) { 63 std::string keyword = words.at(pointer); 64 if (keyword == DataQuery::EQUAL_TO) { 65 isSuccess = HandleEqualTo(words, pointer, end, dbQuery); 66 } else if (keyword == DataQuery::NOT_EQUAL_TO) { 67 isSuccess = HandleNotEqualTo(words, pointer, end, dbQuery); 68 } else if (keyword == DataQuery::GREATER_THAN) { 69 isSuccess = HandleGreaterThan(words, pointer, end, dbQuery); 70 } else if (keyword == DataQuery::LESS_THAN) { 71 isSuccess = HandleLessThan(words, pointer, end, dbQuery); 72 } else if (keyword == DataQuery::GREATER_THAN_OR_EQUAL_TO) { 73 isSuccess = HandleGreaterThanOrEqualTo(words, pointer, end, dbQuery); 74 } else if (keyword == DataQuery::LESS_THAN_OR_EQUAL_TO) { 75 isSuccess = HandleLessThanOrEqualTo(words, pointer, end, dbQuery); 76 } else { 77 isSuccess = Handle(words, pointer, end, dbQuery); 78 } 79 if (!isSuccess) { 80 ZLOGE("Invalid params."); 81 return DBQuery::Select(); 82 } 83 } 84 return dbQuery; 85 } 86 Handle(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)87 bool QueryHelper::Handle(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 88 { 89 std::string keyword = words.at(pointer); 90 if (keyword == DataQuery::IS_NULL) { 91 return HandleIsNull(words, pointer, end, dbQuery); 92 } else if (keyword == DataQuery::IN) { 93 return HandleIn(words, pointer, end, dbQuery); 94 } else if (keyword == DataQuery::NOT_IN) { 95 return HandleNotIn(words, pointer, end, dbQuery); 96 } else if (keyword == DataQuery::LIKE) { 97 return HandleLike(words, pointer, end, dbQuery); 98 } else if (keyword == DataQuery::NOT_LIKE) { 99 return HandleNotLike(words, pointer, end, dbQuery); 100 } else if (keyword == DataQuery::AND) { 101 return HandleAnd(words, pointer, end, dbQuery); 102 } else if (keyword == DataQuery::OR) { 103 return HandleOr(words, pointer, end, dbQuery); 104 } else if (keyword == DataQuery::ORDER_BY_ASC) { 105 return HandleOrderByAsc(words, pointer, end, dbQuery); 106 } else if (keyword == DataQuery::ORDER_BY_DESC) { 107 return HandleOrderByDesc(words, pointer, end, dbQuery); 108 } else if (keyword == DataQuery::ORDER_BY_WRITE_TIME) { 109 return HandleOrderByWriteTime(words, pointer, end, dbQuery); 110 } else if (keyword == DataQuery::LIMIT) { 111 return HandleLimit(words, pointer, end, dbQuery); 112 } else { 113 return HandleExtra(words, pointer, end, dbQuery); 114 } 115 } 116 HandleExtra(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)117 bool QueryHelper::HandleExtra(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 118 { 119 std::string keyword = words.at(pointer); 120 if (keyword == DataQuery::BEGIN_GROUP) { 121 return HandleBeginGroup(words, pointer, end, dbQuery); 122 } else if (keyword == DataQuery::END_GROUP) { 123 return HandleEndGroup(words, pointer, end, dbQuery); 124 } else if (keyword == DataQuery::KEY_PREFIX) { 125 return HandleKeyPrefix(words, pointer, end, dbQuery); 126 } else if (keyword == DataQuery::IS_NOT_NULL) { 127 return HandleIsNotNull(words, pointer, end, dbQuery); 128 } else if (keyword == DataQuery::DEVICE_ID) { 129 return HandleDeviceId(words, pointer, end, dbQuery); 130 } else if (keyword == DataQuery::SUGGEST_INDEX) { 131 return HandleSetSuggestIndex(words, pointer, end, dbQuery); 132 } else if (keyword == DataQuery::IN_KEYS) { 133 return HandleInKeys(words, pointer, end, dbQuery); 134 } 135 ZLOGE("Invalid keyword."); 136 return false; 137 } 138 HandleEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)139 bool QueryHelper::HandleEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 140 { 141 if (pointer + 3 > end) { // This keyword has 3 following params 142 ZLOGE("EqualTo not enough params."); 143 return false; 144 } 145 const std::string &fieldType = words.at(pointer + 1); // fieldType 146 const std::string &fieldName = words.at(pointer + 2); // fieldName 147 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 148 if (fieldType == DataQuery::TYPE_INTEGER) { 149 dbQuery.EqualTo(StringToString(fieldName), StringToInt(fieldValue)); 150 } else if (fieldType == DataQuery::TYPE_LONG) { 151 dbQuery.EqualTo(StringToString(fieldName), StringToLong(fieldValue)); 152 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 153 dbQuery.EqualTo(StringToString(fieldName), StringToDouble(fieldValue)); 154 } else if (fieldType == DataQuery::TYPE_BOOLEAN) { 155 dbQuery.EqualTo(StringToString(fieldName), StringToBoolean(fieldValue)); 156 } else if (fieldType == DataQuery::TYPE_STRING) { 157 dbQuery.EqualTo(StringToString(fieldName), StringToString(fieldValue)); 158 } else { 159 ZLOGE("EqualTo wrong type."); 160 return false; 161 } 162 pointer += 4; // 4 Pointer goes to next keyword 163 return true; 164 } 165 HandleNotEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)166 bool QueryHelper::HandleNotEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 167 { 168 if (pointer + 3 > end) { // This keyword has 3 following params 169 ZLOGE("NotEqualTo not enough params."); 170 return false; 171 } 172 const std::string &fieldType = words.at(pointer + 1); // fieldType 173 const std::string &fieldName = words.at(pointer + 2); // fieldName 174 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 175 if (fieldType == DataQuery::TYPE_INTEGER) { 176 dbQuery.NotEqualTo(StringToString(fieldName), StringToInt(fieldValue)); 177 } else if (fieldType == DataQuery::TYPE_LONG) { 178 dbQuery.NotEqualTo(StringToString(fieldName), StringToLong(fieldValue)); 179 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 180 dbQuery.NotEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); 181 } else if (fieldType == DataQuery::TYPE_BOOLEAN) { 182 dbQuery.NotEqualTo(StringToString(fieldName), StringToBoolean(fieldValue)); 183 } else if (fieldType == DataQuery::TYPE_STRING) { 184 dbQuery.NotEqualTo(StringToString(fieldName), StringToString(fieldValue)); 185 } else { 186 ZLOGE("NotEqualTo wrong type."); 187 return false; 188 } 189 pointer += 4; // 4 Pointer goes to next keyword 190 return true; 191 } 192 HandleGreaterThan(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)193 bool QueryHelper::HandleGreaterThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 194 { 195 if (pointer + 3 > end) { // This keyword has 3 following params 196 ZLOGE("GreaterThan not enough params."); 197 return false; 198 } 199 const std::string &fieldType = words.at(pointer + 1); // fieldType 200 const std::string &fieldName = words.at(pointer + 2); // fieldName 201 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 202 if (fieldType == DataQuery::TYPE_INTEGER) { 203 dbQuery.GreaterThan(StringToString(fieldName), StringToInt(fieldValue)); 204 } else if (fieldType == DataQuery::TYPE_LONG) { 205 dbQuery.GreaterThan(StringToString(fieldName), StringToLong(fieldValue)); 206 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 207 dbQuery.GreaterThan(StringToString(fieldName), StringToDouble(fieldValue)); 208 } else if (fieldType == DataQuery::TYPE_STRING) { 209 dbQuery.GreaterThan(StringToString(fieldName), StringToString(fieldValue)); 210 } else { 211 ZLOGE("GreaterThan wrong type."); 212 return false; 213 } 214 pointer += 4; // 4 Pointer goes to next keyword 215 return true; 216 } 217 HandleLessThan(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)218 bool QueryHelper::HandleLessThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 219 { 220 if (pointer + 3 > end) { // This keyword has 3 following params 221 ZLOGE("LessThan not enough params."); 222 return false; 223 } 224 const std::string &fieldType = words.at(pointer + 1); // fieldType 225 const std::string &fieldName = words.at(pointer + 2); // fieldName 226 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 227 if (fieldType == DataQuery::TYPE_INTEGER) { 228 dbQuery.LessThan(StringToString(fieldName), StringToInt(fieldValue)); 229 } else if (fieldType == DataQuery::TYPE_LONG) { 230 dbQuery.LessThan(StringToString(fieldName), StringToLong(fieldValue)); 231 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 232 dbQuery.LessThan(StringToString(fieldName), StringToDouble(fieldValue)); 233 } else if (fieldType == DataQuery::TYPE_STRING) { 234 dbQuery.LessThan(StringToString(fieldName), StringToString(fieldValue)); 235 } else { 236 ZLOGE("LessThan wrong type."); 237 return false; 238 } 239 pointer += 4; // 4 Pointer goes to next keyword 240 return true; 241 } 242 HandleGreaterThanOrEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)243 bool QueryHelper::HandleGreaterThanOrEqualTo( 244 const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 245 { 246 if (pointer + 3 > end) { // This keyword has 3 following params 247 ZLOGE("GreaterThanOrEqualTo not enough params."); 248 return false; 249 } 250 const std::string &fieldType = words.at(pointer + 1); // fieldType 251 const std::string &fieldName = words.at(pointer + 2); // fieldName 252 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 253 if (fieldType == DataQuery::TYPE_INTEGER) { 254 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue)); 255 } else if (fieldType == DataQuery::TYPE_LONG) { 256 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue)); 257 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 258 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); 259 } else if (fieldType == DataQuery::TYPE_STRING) { 260 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue)); 261 } else { 262 ZLOGE("GreaterThanOrEqualTo wrong type."); 263 return false; 264 } 265 pointer += 4; // 4 Pointer goes to next keyword 266 return true; 267 } 268 HandleLessThanOrEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)269 bool QueryHelper::HandleLessThanOrEqualTo( 270 const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 271 { 272 if (pointer + 3 > end) { // This keyword has 3 following params 273 ZLOGE("LessThanOrEqualTo not enough params."); 274 return false; 275 } 276 const std::string &fieldType = words.at(pointer + 1); // fieldType 277 const std::string &fieldName = words.at(pointer + 2); // fieldName 278 const std::string &fieldValue = words.at(pointer + 3); // fieldValue 279 if (fieldType == DataQuery::TYPE_INTEGER) { 280 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue)); 281 } else if (fieldType == DataQuery::TYPE_LONG) { 282 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue)); 283 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 284 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); 285 } else if (fieldType == DataQuery::TYPE_STRING) { 286 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue)); 287 } else { 288 ZLOGE("LessThanOrEqualTo wrong type."); 289 return false; 290 } 291 pointer += 4; // 4 Pointer goes to next keyword 292 return true; 293 } 294 HandleIsNull(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)295 bool QueryHelper::HandleIsNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 296 { 297 if (pointer + 1 > end) { // This keyword has 1 following params 298 ZLOGE("IsNull not enough params."); 299 return false; 300 } 301 const std::string &fieldName = words.at(pointer + 1); // fieldName 302 dbQuery.IsNull(StringToString(fieldName)); 303 pointer += 2; // 2 Pointer goes to next keyword 304 return true; 305 } 306 HandleIsNotNull(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)307 bool QueryHelper::HandleIsNotNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 308 { 309 if (pointer + 1 > end) { // This keyword has 1 following params 310 ZLOGE("IsNotNull not enough params."); 311 return false; 312 } 313 const std::string &fieldName = words.at(pointer + 1); // fieldName 314 dbQuery.IsNotNull(StringToString(fieldName)); 315 pointer += 2; // 2 Pointer goes to next keyword 316 return true; 317 } 318 HandleIn(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)319 bool QueryHelper::HandleIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 320 { 321 // | <-------------------------4---------------------------->| 322 // words [ DataQuery::IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ] 323 // index [ -------0-----, ----1----, ----2----, ---------3---------, ... , ---------n--------] 324 // ^ ^ 325 // | | 326 // pointer end 327 // first fieldValue, or END if list is empty 328 if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) { 329 ZLOGE("In not enough params."); 330 return false; 331 } 332 const std::string &fieldType = words.at(pointer + 1); // fieldType 333 const std::string &fieldName = words.at(pointer + 2); // fieldName 334 int elementPointer = pointer + 4; // first fieldValue, or END if list is empty 335 if (fieldType == DataQuery::TYPE_INTEGER) { 336 const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end); 337 dbQuery.In(StringToString(fieldName), intValueList); 338 } else if (fieldType == DataQuery::TYPE_LONG) { 339 const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end); 340 dbQuery.In(StringToString(fieldName), longValueList); 341 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 342 const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end); 343 dbQuery.In(StringToString(fieldName), doubleValueList); 344 } else if (fieldType == DataQuery::TYPE_STRING) { 345 const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end); 346 dbQuery.In(StringToString(fieldName), stringValueList); 347 } else { 348 ZLOGE("In wrong type."); 349 return false; 350 } 351 pointer = elementPointer + 1; // Pointer goes to next keyword 352 return true; 353 } 354 HandleNotIn(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)355 bool QueryHelper::HandleNotIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 356 { 357 // |<--------------------------4-------------------------------->| 358 // words [ DataQuery::NOT_IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ] 359 // index [ --------0--------, ----1----, ----2----, ---------3---------, ... , ---------n--------] 360 // ^ ^ 361 // | | 362 // pointer end 363 // first fieldValue, or END if list is empty 364 if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) { 365 ZLOGE("NotIn not enough params."); 366 return false; 367 } 368 const std::string &fieldType = words.at(pointer + 1); // fieldType 369 const std::string &fieldName = words.at(pointer + 2); // fieldName 370 int elementPointer = pointer + 4; // first fieldValue, or END if list is empty 371 if (fieldType == DataQuery::TYPE_INTEGER) { 372 const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end); 373 dbQuery.NotIn(StringToString(fieldName), intValueList); 374 } else if (fieldType == DataQuery::TYPE_LONG) { 375 const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end); 376 dbQuery.NotIn(StringToString(fieldName), longValueList); 377 } else if (fieldType == DataQuery::TYPE_DOUBLE) { 378 const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end); 379 dbQuery.NotIn(StringToString(fieldName), doubleValueList); 380 } else if (fieldType == DataQuery::TYPE_STRING) { 381 const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end); 382 dbQuery.NotIn(StringToString(fieldName), stringValueList); 383 } else { 384 ZLOGE("NotIn wrong type."); 385 return false; 386 } 387 pointer = elementPointer + 1; // Pointer goes to next keyword 388 return true; 389 } 390 HandleLike(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)391 bool QueryHelper::HandleLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 392 { 393 if (pointer + 2 > end) { // This keyword has 2 following params 394 ZLOGE("Like not enough params."); 395 return false; 396 } 397 const std::string &fieldName = words.at(pointer + 1); // fieldName 398 const std::string &fieldValue = words.at(pointer + 2); // fieldValue 399 dbQuery.Like(StringToString(fieldName), StringToString(fieldValue)); 400 pointer += 3; // 3 Pointer goes to next keyword 401 return true; 402 } 403 HandleNotLike(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)404 bool QueryHelper::HandleNotLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 405 { 406 if (pointer + 2 > end) { // This keyword has 2 following params 407 ZLOGE("NotLike not enough params."); 408 return false; 409 } 410 const std::string &fieldName = words.at(pointer + 1); // fieldName 411 const std::string &fieldValue = words.at(pointer + 2); // fieldValue 412 dbQuery.NotLike(StringToString(fieldName), StringToString(fieldValue)); 413 pointer += 3; // 3 Pointer goes to next keyword 414 return true; 415 } 416 HandleAnd(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)417 bool QueryHelper::HandleAnd(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 418 { 419 dbQuery.And(); 420 pointer += 1; // Pointer goes to next keyword 421 return true; 422 } 423 HandleOr(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)424 bool QueryHelper::HandleOr(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 425 { 426 dbQuery.Or(); 427 pointer += 1; // Pointer goes to next keyword 428 return true; 429 } 430 HandleOrderByAsc(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)431 bool QueryHelper::HandleOrderByAsc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 432 { 433 if (pointer + 1 > end) { // This keyword has 1 following params 434 ZLOGE("OrderByAsc not enough params."); 435 return false; 436 } 437 const std::string &fieldName = words.at(pointer + 1); // fieldName 438 dbQuery.OrderBy(StringToString(fieldName), true); 439 pointer += 2; // 2 Pointer goes to next keyword 440 return true; 441 } 442 HandleOrderByDesc(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)443 bool QueryHelper::HandleOrderByDesc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 444 { 445 if (pointer + 1 > end) { // This keyword has 1 following params 446 ZLOGE("OrderByDesc not enough params."); 447 return false; 448 } 449 const std::string &fieldName = words.at(pointer + 1); // fieldName 450 dbQuery.OrderBy(StringToString(fieldName), false); 451 pointer += 2; // 2 Pointer goes to next keyword 452 return true; 453 } 454 HandleOrderByWriteTime(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)455 bool QueryHelper::HandleOrderByWriteTime(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 456 { 457 if (pointer + 1 > end) { // This keyword has 1 following params 458 ZLOGE("HandleOrderByWriteTime not enough params."); 459 return false; 460 } 461 const std::string isAsc = words.at(pointer + 1); // isASC 462 463 dbQuery.OrderByWriteTime(isAsc == DataQuery::IS_ASC); 464 pointer += 2; // 2 Pointer goes to next keyword 465 return true; 466 } 467 HandleLimit(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)468 bool QueryHelper::HandleLimit(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 469 { 470 if (pointer + 2 > end) { // This keyword has 2 following params 471 ZLOGE("Limit not enough params."); 472 return false; 473 } 474 const int number = StringToInt(words.at(pointer + 1)); // number 475 const int offset = StringToInt(words.at(pointer + 2)); // offset 476 dbQuery.Limit(number, offset); 477 pointer += 3; // 3 Pointer goes to next keyword 478 return true; 479 } 480 HandleBeginGroup(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)481 bool QueryHelper::HandleBeginGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 482 { 483 dbQuery.BeginGroup(); 484 pointer += 1; // Pointer goes to next keyword 485 return true; 486 } 487 HandleEndGroup(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)488 bool QueryHelper::HandleEndGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 489 { 490 dbQuery.EndGroup(); 491 pointer += 1; // Pointer goes to next keyword 492 return true; 493 } 494 HandleKeyPrefix(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)495 bool QueryHelper::HandleKeyPrefix(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 496 { 497 if (pointer + 1 > end) { // This keyword has 1 following params 498 ZLOGE("KeyPrefix not enough params."); 499 return false; 500 } 501 const std::string &prefix = deviceId_ + StringToString(words.at(pointer + 1)); // prefix 502 const std::vector<uint8_t> prefixVector(prefix.begin(), prefix.end()); 503 dbQuery.PrefixKey(prefixVector); 504 pointer += 2; // 2 Pointer goes to next keyword 505 return true; 506 } 507 HandleInKeys(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)508 bool QueryHelper::HandleInKeys(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 509 { 510 // pointer points at keyword "IN_KEYS", (pointer + 1) points at keyword "START_IN" 511 int startInOffSet = pointer + 1; 512 int queryLen = end - pointer; 513 if (queryLen < 2 || words.at(startInOffSet) != DataQuery::START_IN) { // This keyword has at least 2 params 514 ZLOGE("In not enough params."); 515 return false; 516 } 517 int inkeyOffSet = startInOffSet + 1; // inkeyOffSet points at the first inkey value 518 const std::vector<std::string> inKeys = GetStringList(words, inkeyOffSet, end); 519 std::set<std::vector<uint8_t>> inDbKeys; 520 for (const std::string &inKey : inKeys) { 521 ZLOGI("inKey=%{public}s", inKey.c_str()); 522 std::vector<uint8_t> dbKey; 523 dbKey.assign(inKey.begin(), inKey.end()); 524 inDbKeys.insert(dbKey); 525 } 526 int size = inDbKeys.size(); 527 ZLOGI("size of inKeys=%{public}d", size); 528 dbQuery.InKeys(inDbKeys); 529 int endOffSet = inkeyOffSet; 530 pointer = endOffSet + 1; // endOffSet points at keyword "END", Pointer goes to next keyword 531 return true; 532 } 533 HandleSetSuggestIndex(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)534 bool QueryHelper::HandleSetSuggestIndex(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 535 { 536 if (pointer + QUERY_SKIP_SIZE > end) { 537 ZLOGE("HandleSetSuggestIndex not enough params."); 538 return false; 539 } 540 std::string index = StringToString(words.at(pointer + QUERY_SKIP_SIZE)); 541 dbQuery.SuggestIndex(index); 542 pointer += QUERY_WORD_SIZE; 543 return true; 544 } 545 HandleDeviceId(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)546 bool QueryHelper::HandleDeviceId(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) 547 { 548 if (pointer + 1 > end) { // This keyword has 1 following params 549 ZLOGE("DeviceId not enough params."); 550 return false; 551 } 552 deviceId_ = StringToString(words.at(pointer + 1)); // deviceId 553 ZLOGI("query devId string length:%zu", deviceId_.length()); 554 deviceId_ = DistributedData::DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(deviceId_); // convert to UUId 555 ZLOGI("query converted devId string length:%zu", deviceId_.length()); 556 if (!hasPrefixKey_) { 557 ZLOGD("DeviceId as the only prefixKey."); 558 const std::vector<uint8_t> prefixVector(deviceId_.begin(), deviceId_.end()); 559 dbQuery.PrefixKey(prefixVector); 560 } else { 561 ZLOGD("Join deviceId with user specified prefixkey later."); 562 } 563 pointer += 2; // 2 Pointer goes to next keyword 564 return true; 565 } 566 StringToInt(const std::string & word)567 int QueryHelper::StringToInt(const std::string &word) 568 { 569 int result; 570 std::istringstream(word) >> result; 571 return result; 572 } 573 StringToLong(const std::string & word)574 int64_t QueryHelper::StringToLong(const std::string &word) 575 { 576 int64_t result; 577 std::istringstream(word) >> result; 578 return result; 579 } 580 StringToDouble(const std::string & word)581 double QueryHelper::StringToDouble(const std::string &word) 582 { 583 double result; 584 std::istringstream(word) >> result; 585 return result; 586 } 587 StringToBoolean(const std::string & word)588 bool QueryHelper::StringToBoolean(const std::string &word) 589 { 590 if (word == DataQuery::VALUE_TRUE) { 591 return true; 592 } else if (word == DataQuery::VALUE_FALSE) { 593 return false; 594 } else { 595 ZLOGE("StringToBoolean wrong value."); 596 return false; 597 } 598 } 599 StringToString(const std::string & word)600 std::string QueryHelper::StringToString(const std::string &word) 601 { 602 std::string result = word; 603 if (result.compare(DataQuery::EMPTY_STRING) == 0) { 604 result = ""; 605 return result; 606 } 607 size_t index = 0; // search from the beginning of the string 608 while (true) { 609 index = result.find(DataQuery::SPACE_ESCAPE, index); 610 if (index == std::string::npos) { 611 break; 612 } 613 result.replace(index, 2, DataQuery::SPACE); // 2 chars to be replaced 614 index += 1; // replaced with 1 char, keep searching the remaining string 615 } 616 index = 0; // search from the beginning of the string 617 while (true) { 618 index = result.find(DataQuery::SPECIAL_ESCAPE, index); 619 if (index == std::string::npos) { 620 break; 621 } 622 result.replace(index, 3, DataQuery::SPECIAL); // 3 chars to be replaced 623 index += 1; // replaced with 1 char, keep searching the remaining string 624 } 625 return result; 626 } 627 GetIntegerList(const std::vector<std::string> & words,int & elementPointer,int end)628 std::vector<int> QueryHelper::GetIntegerList(const std::vector<std::string> &words, int &elementPointer, int end) 629 { 630 std::vector<int> valueList; 631 bool isEndFound = false; 632 while (elementPointer <= end) { 633 if (words.at(elementPointer) == DataQuery::END_IN) { 634 isEndFound = true; 635 break; 636 } 637 valueList.push_back(StringToInt(words.at(elementPointer))); 638 elementPointer++; 639 } 640 if (isEndFound) { 641 return valueList; 642 } else { 643 ZLOGE("GetIntegerList failed."); 644 return std::vector<int>(); 645 } 646 } 647 GetLongList(const std::vector<std::string> & words,int & elementPointer,int end)648 std::vector<int64_t> QueryHelper::GetLongList(const std::vector<std::string> &words, int &elementPointer, int end) 649 { 650 std::vector<int64_t> valueList; 651 bool isEndFound = false; 652 while (elementPointer <= end) { 653 if (words.at(elementPointer) == DataQuery::END_IN) { 654 isEndFound = true; 655 break; 656 } 657 valueList.push_back(StringToLong(words.at(elementPointer))); 658 elementPointer++; 659 } 660 if (isEndFound) { 661 return valueList; 662 } else { 663 ZLOGE("GetLongList failed."); 664 return std::vector<int64_t>(); 665 } 666 } 667 GetDoubleList(const std::vector<std::string> & words,int & elementPointer,int end)668 std::vector<double> QueryHelper::GetDoubleList(const std::vector<std::string> &words, int &elementPointer, int end) 669 { 670 std::vector<double> valueList; 671 bool isEndFound = false; 672 while (elementPointer <= end) { 673 if (words.at(elementPointer) == DataQuery::END_IN) { 674 isEndFound = true; 675 break; 676 } 677 valueList.push_back(StringToDouble(words.at(elementPointer))); 678 elementPointer++; 679 } 680 if (isEndFound) { 681 return valueList; 682 } else { 683 ZLOGE("GetDoubleList failed."); 684 return std::vector<double>(); 685 } 686 } 687 GetStringList(const std::vector<std::string> & words,int & elementPointer,int end)688 std::vector<std::string> QueryHelper::GetStringList(const std::vector<std::string> &words, int &elementPointer, int end) 689 { 690 std::vector<std::string> valueList; 691 bool isEndFound = false; 692 while (elementPointer <= end) { 693 if (words.at(elementPointer) == DataQuery::END_IN) { 694 isEndFound = true; 695 break; 696 } 697 valueList.push_back(StringToString(words.at(elementPointer))); 698 elementPointer++; 699 } 700 if (isEndFound) { 701 return valueList; 702 } else { 703 ZLOGE("GetStringList failed."); 704 return std::vector<std::string>(); 705 } 706 } 707 } // namespace OHOS::DistributedKv 708