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 16 #ifndef DISTRIBUTED_KVSTORE_TYPES_H 17 #define DISTRIBUTED_KVSTORE_TYPES_H 18 19 #include <algorithm> 20 #include <cstdint> 21 #include <string> 22 #include <variant> 23 #include <vector> 24 #include "blob.h" 25 #include "store_errno.h" 26 #include "visibility.h" 27 28 namespace OHOS { 29 namespace DistributedKv { 30 /** 31 * @brief Key set by client, can be any non-empty bytes array, and less than 1024 size. 32 */ 33 using Key = OHOS::DistributedKv::Blob; 34 35 /** 36 * @brief Value set by client, can be any bytes array. 37 */ 38 using Value = OHOS::DistributedKv::Blob; 39 40 /** 41 * @brief User identifier from user-account. 42 */ 43 struct UserId { 44 std::string userId; 45 }; 46 47 /** 48 * @brief App identifier from bms. 49 */ 50 struct API_EXPORT AppId { 51 std::string appId; 52 53 /** 54 * @brief Support appId convert to std::string. 55 */ 56 operator std::string &() noexcept 57 { 58 return appId; 59 } 60 61 /** 62 * @brief Support appId convert to const std::string. 63 */ 64 operator const std::string &() const noexcept 65 { 66 return appId; 67 } 68 69 /** 70 * @brief Check appId. 71 */ IsValidAppId72 inline bool IsValid() const 73 { 74 if (appId.empty() || appId.size() > MAX_APP_ID_LEN) { 75 return false; 76 } 77 int count = 0; 78 auto iter = std::find_if_not(appId.begin(), appId.end(), 79 [&count](char c) { 80 count = (c == SEPARATOR_CHAR) ? (count + 1) : (count >= SEPARATOR_COUNT ? count : 0); 81 return (std::isprint(c) && c != '/'); 82 }); 83 84 return (iter == appId.end()) && (count < SEPARATOR_COUNT); 85 } 86 private: 87 static constexpr int MAX_APP_ID_LEN = 256; 88 static constexpr int SEPARATOR_COUNT = 3; 89 static constexpr char SEPARATOR_CHAR = '#'; 90 }; 91 92 /** 93 * @brief Kvstore name set by client by calling GetKvStore. 94 * 95 * storeId length must be less or equal than 256, 96 * and can not be empty and all space. 97 */ 98 struct API_EXPORT StoreId { 99 std::string storeId; 100 101 /** 102 * @brief Support storeId convert to std::string. 103 */ 104 operator std::string &() noexcept 105 { 106 return storeId; 107 } 108 109 /** 110 * @brief Support storeId convert to const std::string. 111 */ 112 operator const std::string &() const noexcept 113 { 114 return storeId; 115 } 116 117 /** 118 * @brief Operator <. 119 */ 120 bool operator<(const StoreId &id) const noexcept 121 { 122 return this->storeId < id.storeId; 123 } 124 125 /** 126 * @brief Check storeId. 127 */ IsValidStoreId128 inline bool IsValid() const 129 { 130 if (storeId.empty() || storeId.size() > MAX_STORE_ID_LEN) { 131 return false; 132 } 133 auto iter = std::find_if_not(storeId.begin(), storeId.end(), 134 [](char c) { return (std::isdigit(c) || std::isalpha(c) || c == '_'); }); 135 return (iter == storeId.end()); 136 } 137 private: 138 static constexpr int MAX_STORE_ID_LEN = 128; 139 }; 140 141 /** 142 * @brief Identifier unique database. 143 */ 144 struct KvStoreTuple { 145 std::string userId; 146 std::string appId; 147 std::string storeId; 148 }; 149 150 /** 151 * @brief App thread information. 152 */ 153 struct AppThreadInfo { 154 std::int32_t pid; 155 std::int32_t uid; 156 }; 157 158 /** 159 * @brief The type for observer database change. 160 */ 161 enum SubscribeType : uint32_t { 162 /** 163 * Local changes of syncable kv store. 164 */ 165 SUBSCRIBE_TYPE_LOCAL = 1, 166 /** 167 * Synced data changes from remote devices 168 */ 169 SUBSCRIBE_TYPE_REMOTE = 2, 170 /** 171 * Synced data changes from remote devices 172 */ 173 SUBSCRIBE_TYPE_CLOUD = 4, 174 /** 175 * Both local changes and synced data changes. 176 */ 177 SUBSCRIBE_TYPE_ALL = 7, 178 }; 179 180 struct DataOrigin { 181 enum OriginType : int32_t { 182 ORIGIN_NEARBY, 183 ORIGIN_CLOUD, 184 ORIGIN_ALL, 185 ORIGIN_BUTT, 186 }; 187 int32_t origin = ORIGIN_ALL; 188 // origin is ORIGIN_NEARBY, the id is networkId; 189 // origin is ORIGIN_CLOUD, the id is the cloud account id 190 std::vector<std::string> id; 191 std::string store; 192 }; 193 194 /** 195 * @brief Data is organized by entry definition. 196 */ 197 struct Entry { 198 Key key; 199 Value value; 200 201 static constexpr size_t MAX_KEY_LENGTH = 1024; 202 static constexpr size_t MAX_VALUE_LENGTH = 4 * 1024 * 1024; 203 204 /** 205 * Write blob size and data to memory buffer. 206 * Return error when bufferLeftSize not enough. 207 */ WriteToBufferEntry208 bool WriteToBuffer(uint8_t *&cursorPtr, int &bufferLeftSize) const 209 { 210 return key.WriteToBuffer(cursorPtr, bufferLeftSize) && value.WriteToBuffer(cursorPtr, bufferLeftSize); 211 } 212 213 /** 214 * Read a blob from memory buffer. 215 */ ReadFromBufferEntry216 bool ReadFromBuffer(const uint8_t *&cursorPtr, int &bufferLeftSize) 217 { 218 return key.ReadFromBuffer(cursorPtr, bufferLeftSize) && value.ReadFromBuffer(cursorPtr, bufferLeftSize); 219 } 220 RawSizeEntry221 int RawSize() const 222 { 223 return key.RawSize() + value.RawSize(); 224 } 225 }; 226 227 /** 228 * @brief Indicate how to sync data on sync operation. 229 */ 230 enum SyncMode : int32_t { 231 /** 232 * Sync remote data to local. 233 */ 234 PULL, 235 /** 236 * Sync local data to remote. 237 */ 238 PUSH, 239 /** 240 * Both push and pull. 241 */ 242 PUSH_PULL, 243 }; 244 245 /** 246 * @brief The kvstore type. 247 */ 248 enum KvStoreType : int32_t { 249 /** 250 * Multi-device collaboration. 251 * The data is managed by the dimension of the device, 252 * and there is no conflict. 253 * Support to query data according to the dimension of equipment. 254 */ 255 DEVICE_COLLABORATION, 256 /** 257 * Data is not divided into devices. 258 * Modifying the same key between devices will overwrite. 259 */ 260 SINGLE_VERSION, 261 /** 262 * Not support type. 263 */ 264 MULTI_VERSION, 265 LOCAL_ONLY, 266 INVALID_TYPE, 267 }; 268 269 /** 270 * @brief Enumeration of database security level. 271 */ 272 enum SecurityLevel : int32_t { 273 INVALID_LABEL = -1, 274 NO_LABEL, 275 S0, 276 S1, 277 S2, 278 S3_EX, 279 S3, 280 S4, 281 }; 282 283 /** 284 * @brief Enumeration of database base directory. 285 */ 286 enum Area : int32_t { 287 EL0, 288 EL1, 289 EL2, 290 EL3, 291 EL4 292 }; 293 294 enum KvControlCmd : int32_t { 295 SET_SYNC_PARAM = 1, 296 GET_SYNC_PARAM, 297 }; 298 299 using KvParam = OHOS::DistributedKv::Blob; 300 301 struct KvSyncParam { 302 uint32_t allowedDelayMs { 0 }; 303 }; 304 305 /** 306 * @brief Device basic information. 307 * 308 * Including device id, name and type. 309 */ 310 struct DeviceInfo { 311 std::string deviceId; 312 std::string deviceName; 313 std::string deviceType; 314 }; 315 316 /** 317 * @brief Device filter strategy. 318 */ 319 enum class DeviceFilterStrategy { 320 FILTER = 0, 321 NO_FILTER = 1, 322 }; 323 324 /** 325 * @brief Indicate how and when to sync data with other device. 326 */ 327 enum PolicyType : uint32_t { 328 /** 329 * Data synchronization within valid time. 330 */ 331 TERM_OF_SYNC_VALIDITY, 332 /** 333 * Data synchronization when device manager module call online operation. 334 */ 335 IMMEDIATE_SYNC_ON_ONLINE, 336 /** 337 * Data synchronization when put, delete or update database. 338 */ 339 IMMEDIATE_SYNC_ON_CHANGE, 340 /** 341 * Data synchronization when device manager module call onready operation. 342 */ 343 IMMEDIATE_SYNC_ON_READY, 344 POLICY_BUTT 345 }; 346 347 /** 348 * @brief Policy Type value. 349 */ 350 struct SyncPolicy { 351 uint32_t type; 352 std::variant<std::monostate, uint32_t> value; 353 }; 354 355 /** 356 * @brief Role Type value. 357 */ 358 enum RoleType : uint32_t { 359 /** 360 * The user has administrative rights. 361 */ 362 OWNER = 0, 363 /** 364 * The user has read-only permission. 365 */ 366 VISITOR, 367 }; 368 369 struct Group { 370 std::string groupDir = ""; 371 std::string groupId = ""; 372 }; 373 374 /** 375 * @brief Cloud config 376 */ 377 struct CloudConfig { 378 /** 379 * @brief enable cloud 380 */ 381 bool enableCloud = false; 382 /** 383 * @brief Set cloud sync is auto sync 384 */ 385 bool autoSync = false; 386 }; 387 388 enum IndexType : uint32_t { 389 /** 390 * use btree index type in database 391 */ 392 BTREE = 0, 393 /** 394 * use hash index type in database 395 */ 396 HASH, 397 }; 398 399 /** 400 * @brief Data type, that determined the way and timing of data synchronization. 401 */ 402 enum DataType : uint32_t { 403 /** 404 * TYPE_STATICS: means synchronize on link establishment or device online. 405 */ 406 TYPE_STATICS = 0, 407 408 /** 409 * TYPE_DYNAMICAL: means synchronize on link establishment. 410 * synchronize can also triggered by the sync and async get interface. 411 */ 412 TYPE_DYNAMICAL, 413 }; 414 415 /** 416 * @brief Verify data synchronization based on the account type. 417 */ 418 enum AuthType : uint32_t { 419 /** 420 * DEFAULT: means all types of checks. 421 */ 422 DEFAULT = 0, 423 424 /** 425 * IDENTICAL_ACCOUNT_CHECK: means verify the same account type. 426 */ 427 IDENTICAL_ACCOUNT 428 }; 429 430 /** 431 * @brief Provide configuration information for database creation. 432 */ 433 struct Options { 434 /** 435 * Whether to create a database when the database file does not exist. 436 * It is created by default. 437 */ 438 bool createIfMissing = true; 439 /** 440 * Set whether the database file is encrypted. 441 * It is not encrypted by default. 442 */ 443 bool encrypt = false; 444 /** 445 * Set whether the rekey takes effect. 446 * It does not take effect by default. 447 */ 448 bool autoRekey = false; 449 /** 450 * Data storage disk by default. 451 */ 452 bool persistent = true; 453 /** 454 * Set whether the database file is backed up. 455 * It is back up by default. 456 */ 457 bool backup = true; 458 /** 459 * Set whether the database file is automatically synchronized. 460 * It is not automatically synchronized by default. 461 * 'ohos.permission.DISTRIBUTED_DATASYNC' permission is necessary. 462 * AutoSync do not guarantee real-time consistency, sync interface is suggested if necessary. 463 */ 464 bool autoSync = false; 465 /** 466 * True if is distributed store, false if is local store 467 */ 468 bool syncable = true; 469 /** 470 * Set Whether rebuild the database. 471 */ 472 bool rebuild = false; 473 /** 474 * Set Whether the database is public. 475 */ 476 bool isPublic = false; 477 /** 478 * Set database security level. 479 */ 480 int32_t securityLevel = INVALID_LABEL; 481 /** 482 * Set database directory area. 483 */ 484 int32_t area = EL1; 485 /** 486 * Set the type of database to be created. 487 * The default is multi-device collaboration database. 488 */ 489 KvStoreType kvStoreType = DEVICE_COLLABORATION; 490 /** 491 * The sync policy vector. 492 */ 493 std::vector<SyncPolicy> policies{ { IMMEDIATE_SYNC_ON_CHANGE } }; 494 /** 495 * Set the value stored in the database. 496 * Schema is not used by default. 497 */ 498 std::string schema = ""; 499 /** 500 * Set database directory hapName. 501 */ 502 std::string hapName = ""; 503 /** 504 * Set database directory baseDir. 505 */ 506 std::string baseDir = ""; 507 /** 508 * Whether the kvstore type is valid. 509 */ IsValidTypeOptions510 inline bool IsValidType() const 511 { 512 bool isValid = kvStoreType == KvStoreType::DEVICE_COLLABORATION || 513 kvStoreType == KvStoreType::SINGLE_VERSION || kvStoreType == KvStoreType::LOCAL_ONLY; 514 return isValid && (dataType == DataType::TYPE_STATICS || dataType == DataType::TYPE_DYNAMICAL); 515 } 516 /** 517 * Get the databaseDir. 518 */ GetDatabaseDirOptions519 inline std::string GetDatabaseDir() const 520 { 521 if (baseDir.empty()) { 522 return group.groupDir; 523 } 524 return !group.groupDir.empty() ? "" : baseDir; 525 } 526 /** 527 * Whether the databaseDir is valid. 528 */ IsPathValidOptions529 inline bool IsPathValid() const 530 { 531 if ((baseDir.empty() && group.groupDir.empty()) || (!baseDir.empty() && !group.groupDir.empty())) { 532 return false; 533 } 534 return true; 535 } 536 Group group; 537 /** 538 * Set database role. 539 */ 540 RoleType role; 541 /** 542 * Whether the sync happend in client. 543 */ 544 bool isClientSync = false; 545 /** 546 * Whether the sync need compress. 547 */ 548 bool isNeedCompress = true; 549 /** 550 * Indicates data type. 551 * Only dynamic data support auto sync. 552 */ 553 DataType dataType = DataType::TYPE_DYNAMICAL; 554 /** 555 * config database details. 556 */ 557 struct Config { 558 IndexType type = BTREE; 559 uint32_t pageSize = 32u; 560 uint32_t cacheSize = 2048u; 561 } config; 562 /** 563 * Set cloud config of kv store. 564 */ 565 CloudConfig cloudConfig; 566 /** 567 * Set authType of kv store. 568 */ 569 AuthType authType = AuthType::DEFAULT; 570 /** 571 * Sub user config for system ability. 572 */ 573 int32_t subUser = 0; 574 }; 575 576 /** 577 * @brief Provide the user information. 578 */ 579 struct UserInfo { 580 /** 581 * The userId Info. 582 */ 583 std::string userId; 584 585 /** 586 * The userType Info. 587 */ 588 int32_t userType; 589 }; 590 591 /** 592 * @brief Cloud sync progress status. 593 */ 594 enum Progress { 595 SYNC_BEGIN = 0, 596 SYNC_IN_PROGRESS, 597 SYNC_FINISH, 598 }; 599 600 /** 601 * @brief Cloud sync statistic. 602 */ 603 struct Statistic { 604 uint32_t total; 605 uint32_t success; 606 uint32_t failed; 607 uint32_t untreated; 608 }; 609 610 /** 611 * @brief Cloud sync table detail. 612 */ 613 struct TableDetail { 614 Statistic upload; 615 Statistic download; 616 }; 617 618 /** 619 * @brief Cloud sync process detail. 620 */ 621 struct ProgressDetail { 622 /** 623 * Cloud sync progress status 624 */ 625 int32_t progress; 626 int32_t code; 627 TableDetail details; 628 }; 629 630 using AsyncDetail = std::function<void(ProgressDetail &&)>; 631 632 /** 633 * @brief Provide the switch data. 634 */ 635 struct SwitchData { 636 /** 637 * The value of switch data, one bit represents a switch state. 638 */ 639 uint32_t value; 640 641 /** 642 * The effective bit count from low bit to high bit, must be 8, 16 or 24, max is 24. 643 */ 644 uint16_t length; 645 }; 646 647 /** 648 * @brief Switch data opertaion. 649 */ 650 enum SwitchState: uint32_t { 651 /** 652 * INSERT: means insert data. 653 */ 654 INSERT = 0, 655 656 /** 657 * UPDATE: means update data. 658 */ 659 UPDATE, 660 661 /** 662 * DELETE: means delete data. 663 */ 664 DELETE, 665 }; 666 667 /** 668 * @brief Switch data notification for change. 669 */ 670 struct SwitchNotification { 671 /** 672 * Switch data. 673 */ 674 SwitchData data; 675 676 /** 677 * The device networkId. 678 */ 679 std::string deviceId; 680 681 /** 682 * Switch state. 683 */ 684 SwitchState state = SwitchState::INSERT; 685 }; 686 687 /** 688 * @brief Set config of kv store. 689 */ 690 struct StoreConfig { 691 /** 692 * Set cloud config of kv store. 693 */ 694 CloudConfig cloudConfig; 695 }; 696 } // namespace DistributedKv 697 } // namespace OHOS 698 #endif // DISTRIBUTED_KVSTORE_TYPES_H 699