已关闭
fix: 升级react-native-mmkv-storage #12
houahui创建于 1月30日关闭于 27 天前
fix: 升级react-native-mmkv-storage #12
已关闭
共 20 个文件变更+395-82
| @@ -8,6 +8,7 @@ | |||
| 8 | node_modules/ | 8 | node_modules/ |
| 9 | npm-debug.log | 9 | npm-debug.log |
| 10 | yarn-error.log | 10 | yarn-error.log |
| 11 | +**/.xcode.env.local | ||
| 11 | 12 | ||
| 12 | 13 | ||
| 13 | # Xcode | 14 | # Xcode |
| @@ -29,6 +30,8 @@ DerivedData | |||
| 29 | *.ipa | 30 | *.ipa |
| 30 | *.xcuserstate | 31 | *.xcuserstate |
| 31 | project.xcworkspace | 32 | project.xcworkspace |
| 33 | +Pods | ||
| 34 | +vendor | ||
| 32 | 35 | ||
| 33 | 36 | ||
| 34 | # Android/IntelliJ | 37 | # Android/IntelliJ |
| @@ -591,7 +591,6 @@ | |||
| 591 | SKIP_INSTALL = YES; | 591 | SKIP_INSTALL = YES; |
| 592 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; | 592 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; |
| 593 | TARGETED_DEVICE_FAMILY = "1,2,3"; | 593 | TARGETED_DEVICE_FAMILY = "1,2,3"; |
| 594 | - SUPPORTS_MACCATALYST = YES; | ||
| 595 | }; | 594 | }; |
| 596 | name = Debug; | 595 | name = Debug; |
| 597 | }; | 596 | }; |
| @@ -618,7 +617,6 @@ | |||
| 618 | SKIP_INSTALL = YES; | 617 | SKIP_INSTALL = YES; |
| 619 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; | 618 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; |
| 620 | TARGETED_DEVICE_FAMILY = "1,2,3"; | 619 | TARGETED_DEVICE_FAMILY = "1,2,3"; |
| 621 | - SUPPORTS_MACCATALYST = YES; | ||
| 622 | }; | 620 | }; |
| 623 | name = Release; | 621 | name = Release; |
| 624 | }; | 622 | }; |
| @@ -337,11 +337,7 @@ void MMKV::close() { | |||
| 337 | SCOPED_LOCK(g_instanceLock); | 337 | SCOPED_LOCK(g_instanceLock); |
| 338 | m_lock->lock(); | 338 | m_lock->lock(); |
| 339 | 339 | ||
| 340 | -#ifndef MMKV_ANDROID | ||
| 341 | auto itr = g_instanceDic->find(m_mmapKey); | 340 | auto itr = g_instanceDic->find(m_mmapKey); |
| 342 | -#else | ||
| 343 | - auto itr = g_instanceDic->find(m_mmapID); | ||
| 344 | -#endif | ||
| 345 | if (itr != g_instanceDic->end()) { | 341 | if (itr != g_instanceDic->end()) { |
| 346 | g_instanceDic->erase(itr); | 342 | g_instanceDic->erase(itr); |
| 347 | } | 343 | } |
| @@ -779,8 +775,8 @@ void MMKV::shared_lock() { | |||
| 779 | } | 775 | } |
| 780 | 776 | ||
| 781 | void MMKV::shared_unlock() { | 777 | void MMKV::shared_unlock() { |
| 782 | - m_sharedProcessLock->lock(); | 778 | + m_sharedProcessLock->unlock(); |
| 783 | - m_lock->lock(); | 779 | + m_lock->unlock(); |
| 784 | } | 780 | } |
| 785 | 781 | ||
| 786 | #endif // MMKV_APPLE | 782 | #endif // MMKV_APPLE |
| @@ -1290,8 +1286,14 @@ bool MMKV::backupOneToDirectory(const string &mmapID, const MMKVPath_t &dstDir, | |||
| 1290 | auto dstPath = dstDir + MMKV_PATH_SLASH + encodePath; | 1286 | auto dstPath = dstDir + MMKV_PATH_SLASH + encodePath; |
| 1291 | auto mmapKey = mmapedKVKey(mmapID, rootPath); | 1287 | auto mmapKey = mmapedKVKey(mmapID, rootPath); |
| 1292 | #ifdef MMKV_ANDROID | 1288 | #ifdef MMKV_ANDROID |
| 1293 | - // historically Android mistakenly use mmapKey as mmapID | 1289 | + string srcPath; |
| 1294 | - auto srcPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath); | 1290 | + auto correctPath = *rootPath + MMKV_PATH_SLASH + encodePath; |
| 1291 | + if (srcDir && isFileExist(correctPath)) { | ||
| 1292 | + srcPath = correctPath; | ||
| 1293 | + } else { | ||
| 1294 | + // historically Android mistakenly use mmapKey as mmapID | ||
| 1295 | + srcPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath); | ||
| 1296 | + } | ||
| 1295 | #else | 1297 | #else |
| 1296 | auto srcPath = *rootPath + MMKV_PATH_SLASH + encodePath; | 1298 | auto srcPath = *rootPath + MMKV_PATH_SLASH + encodePath; |
| 1297 | #endif | 1299 | #endif |
| @@ -1470,8 +1472,14 @@ bool MMKV::restoreOneFromDirectory(const string &mmapID, const MMKVPath_t &srcDi | |||
| 1470 | auto srcPath = srcDir + MMKV_PATH_SLASH + encodePath; | 1472 | auto srcPath = srcDir + MMKV_PATH_SLASH + encodePath; |
| 1471 | auto mmapKey = mmapedKVKey(mmapID, rootPath); | 1473 | auto mmapKey = mmapedKVKey(mmapID, rootPath); |
| 1472 | #ifdef MMKV_ANDROID | 1474 | #ifdef MMKV_ANDROID |
| 1473 | - // historically Android mistakenly use mmapKey as mmapID | 1475 | + string dstPath; |
| 1474 | - auto dstPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath); | 1476 | + auto correctPath = *rootPath + MMKV_PATH_SLASH + encodePath; |
| 1477 | + if (dstDir && isFileExist(correctPath)) { | ||
| 1478 | + dstPath = correctPath; | ||
| 1479 | + } else { | ||
| 1480 | + // historically Android mistakenly use mmapKey as mmapID | ||
| 1481 | + dstPath = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapKey, *rootPath); | ||
| 1482 | + } | ||
| 1475 | #else | 1483 | #else |
| 1476 | auto dstPath = *rootPath + MMKV_PATH_SLASH + encodePath; | 1484 | auto dstPath = *rootPath + MMKV_PATH_SLASH + encodePath; |
| 1477 | #endif | 1485 | #endif |
| @@ -90,20 +90,20 @@ concept MMKV_SUPPORTED_VALUE_TYPE = MMKV_SUPPORTED_PRIMITIVE_VALUE_TYPE<T> || MM | |||
| 90 | 90 | ||
| 91 | class MMKV { | 91 | class MMKV { |
| 92 | #ifndef MMKV_ANDROID | 92 | #ifndef MMKV_ANDROID |
| 93 | - std::string m_mmapKey; | ||
| 94 | MMKV(const std::string &mmapID, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0); | 93 | MMKV(const std::string &mmapID, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0); |
| 95 | #else // defined(MMKV_ANDROID) | 94 | #else // defined(MMKV_ANDROID) |
| 96 | mmkv::FileLock *m_fileModeLock; | 95 | mmkv::FileLock *m_fileModeLock; |
| 97 | mmkv::InterProcessLock *m_sharedProcessModeLock; | 96 | mmkv::InterProcessLock *m_sharedProcessModeLock; |
| 98 | mmkv::InterProcessLock *m_exclusiveProcessModeLock; | 97 | mmkv::InterProcessLock *m_exclusiveProcessModeLock; |
| 99 | 98 | ||
| 100 | - MMKV(const std::string &mmapID, int size, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0); | 99 | + MMKV(const std::string &mmapID, int size, MMKVMode mode, const std::string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity = 0); |
| 101 | 100 | ||
| 102 | - MMKV(const std::string &mmapID, int ashmemFD, int ashmemMetaFd, std::string *cryptKey = nullptr); | 101 | + MMKV(const std::string &mmapID, int ashmemFD, int ashmemMetaFd, const std::string *cryptKey = nullptr); |
| 103 | #endif | 102 | #endif |
| 104 | 103 | ||
| 105 | ~MMKV(); | 104 | ~MMKV(); |
| 106 | 105 | ||
| 106 | + std::string m_mmapKey; | ||
| 107 | std::string m_mmapID; | 107 | std::string m_mmapID; |
| 108 | MMKVPath_t m_path; | 108 | MMKVPath_t m_path; |
| 109 | MMKVPath_t m_crcPath; | 109 | MMKVPath_t m_crcPath; |
| @@ -220,7 +220,7 @@ class MMKV { | |||
| 220 | void notifyContentChanged(); | 220 | void notifyContentChanged(); |
| 221 | 221 | ||
| 222 | #if defined(MMKV_ANDROID) && !defined(MMKV_DISABLE_CRYPT) | 222 | #if defined(MMKV_ANDROID) && !defined(MMKV_DISABLE_CRYPT) |
| 223 | - void checkReSetCryptKey(int fd, int metaFD, std::string *cryptKey); | 223 | + void checkReSetCryptKey(int fd, int metaFD, const std::string *cryptKey); |
| 224 | #endif | 224 | #endif |
| 225 | static bool backupOneToDirectory(const std::string &mmapKey, const MMKVPath_t &dstPath, const MMKVPath_t &srcPath, bool compareFullPath); | 225 | static bool backupOneToDirectory(const std::string &mmapKey, const MMKVPath_t &dstPath, const MMKVPath_t &srcPath, bool compareFullPath); |
| 226 | static size_t backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &srcDir, bool isInSpecialDir); | 226 | static size_t backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &srcDir, bool isInSpecialDir); |
| @@ -264,11 +264,11 @@ public: | |||
| 264 | static MMKV *mmkvWithID(const std::string &mmapID, | 264 | static MMKV *mmkvWithID(const std::string &mmapID, |
| 265 | int size = mmkv::DEFAULT_MMAP_SIZE, | 265 | int size = mmkv::DEFAULT_MMAP_SIZE, |
| 266 | MMKVMode mode = MMKV_SINGLE_PROCESS, | 266 | MMKVMode mode = MMKV_SINGLE_PROCESS, |
| 267 | - std::string *cryptKey = nullptr, | 267 | + const std::string *cryptKey = nullptr, |
| 268 | - MMKVPath_t *rootPath = nullptr, | 268 | + const MMKVPath_t *rootPath = nullptr, |
| 269 | size_t expectedCapacity = 0); | 269 | size_t expectedCapacity = 0); |
| 270 | 270 | ||
| 271 | - static MMKV *mmkvWithAshmemFD(const std::string &mmapID, int fd, int metaFD, std::string *cryptKey = nullptr); | 271 | + static MMKV *mmkvWithAshmemFD(const std::string &mmapID, int fd, int metaFD, const std::string *cryptKey = nullptr); |
| 272 | 272 | ||
| 273 | int ashmemFD(); | 273 | int ashmemFD(); |
| 274 | 274 | ||
| @@ -577,5 +577,5 @@ bool MMKV::getVector(MMKVKey_t key, T &result) { | |||
| 577 | 577 | ||
| 578 | MMKV_NAMESPACE_END | 578 | MMKV_NAMESPACE_END |
| 579 | 579 | ||
| 580 | -#endif | 580 | +#endif // __cplusplus |
| 581 | #endif // MMKV_MMKV_H | 581 | #endif // MMKV_MMKV_H |
| @@ -34,7 +34,7 @@ | |||
| 34 | #include <vector> | 34 | #include <vector> |
| 35 | #include <unordered_map> | 35 | #include <unordered_map> |
| 36 | 36 | ||
| 37 | -constexpr auto MMKV_VERSION = "v1.3.9"; | 37 | +constexpr auto MMKV_VERSION = "v1.3.14"; |
| 38 | 38 | ||
| 39 | #ifdef DEBUG | 39 | #ifdef DEBUG |
| 40 | # define MMKV_DEBUG | 40 | # define MMKV_DEBUG |
| @@ -39,8 +39,8 @@ using namespace mmkv; | |||
| 39 | extern unordered_map<string, MMKV *> *g_instanceDic; | 39 | extern unordered_map<string, MMKV *> *g_instanceDic; |
| 40 | extern ThreadLock *g_instanceLock; | 40 | extern ThreadLock *g_instanceLock; |
| 41 | 41 | ||
| 42 | -MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity) | 42 | +MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity) |
| 43 | - : m_mmapID((mode & MMKV_BACKUP) ? mmapID : mmapedKVKey(mmapID, rootPath)) // historically Android mistakenly use mmapKey as mmapID | 43 | + : m_mmapID(mmapID) |
| 44 | , m_path(mappedKVPathWithID(m_mmapID, mode, rootPath)) | 44 | , m_path(mappedKVPathWithID(m_mmapID, mode, rootPath)) |
| 45 | , m_crcPath(crcPathWithID(m_mmapID, mode, rootPath)) | 45 | , m_crcPath(crcPathWithID(m_mmapID, mode, rootPath)) |
| 46 | , m_dic(nullptr) | 46 | , m_dic(nullptr) |
| @@ -88,7 +88,7 @@ MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, stri | |||
| 88 | }*/ | 88 | }*/ |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | -MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKey) | 91 | +MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, const string *cryptKey) |
| 92 | : m_mmapID(mmapID) | 92 | : m_mmapID(mmapID) |
| 93 | , m_path(mappedKVPathWithID(m_mmapID, MMKV_ASHMEM, nullptr)) | 93 | , m_path(mappedKVPathWithID(m_mmapID, MMKV_ASHMEM, nullptr)) |
| 94 | , m_crcPath(crcPathWithID(m_mmapID, MMKV_ASHMEM, nullptr)) | 94 | , m_crcPath(crcPathWithID(m_mmapID, MMKV_ASHMEM, nullptr)) |
| @@ -137,8 +137,8 @@ MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKe | |||
| 137 | }*/ | 137 | }*/ |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | -MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity) { | 140 | +MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity) { |
| 141 | - if (mmapID.empty()) { | 141 | + if (mmapID.empty() || !g_instanceLock) { |
| 142 | return nullptr; | 142 | return nullptr; |
| 143 | } | 143 | } |
| 144 | SCOPED_LOCK(g_instanceLock); | 144 | SCOPED_LOCK(g_instanceLock); |
| @@ -157,14 +157,25 @@ MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cr | |||
| 157 | } | 157 | } |
| 158 | MMKVInfo("prepare to load %s (id %s) from rootPath %zu", mmapID.c_str(), mmapKey.c_str(), rootPath->c_str()); | 158 | MMKVInfo("prepare to load %s (id %s) from rootPath %zu", mmapID.c_str(), mmapKey.c_str(), rootPath->c_str()); |
| 159 | } | 159 | } |
| 160 | - auto kv = new MMKV(mmapID, size, mode, cryptKey, rootPath, expectedCapacity); | 160 | + |
| 161 | + string realID; | ||
| 162 | + auto correctPath = mappedKVPathWithID(mmapID, mode, rootPath); | ||
| 163 | + if ((mode & MMKV_BACKUP) || (rootPath && isFileExist(correctPath))) { | ||
| 164 | + // it's successfully migrated to the correct path by newer version of MMKV | ||
| 165 | + realID = mmapID; | ||
| 166 | + } else { | ||
| 167 | + // historically Android mistakenly use mmapKey as mmapID | ||
| 168 | + realID = mmapKey; | ||
| 169 | + } | ||
| 170 | + auto kv = new MMKV(realID, size, mode, cryptKey, rootPath, expectedCapacity); | ||
| 171 | + kv->m_mmapKey = mmapKey; | ||
| 161 | (*g_instanceDic)[mmapKey] = kv; | 172 | (*g_instanceDic)[mmapKey] = kv; |
| 162 | return kv; | 173 | return kv; |
| 163 | } | 174 | } |
| 164 | 175 | ||
| 165 | -MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, string *cryptKey) { | 176 | +MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, const string *cryptKey) { |
| 166 | 177 | ||
| 167 | - if (fd < 0) { | 178 | + if (fd < 0 || !g_instanceLock) { |
| 168 | return nullptr; | 179 | return nullptr; |
| 169 | } | 180 | } |
| 170 | SCOPED_LOCK(g_instanceLock); | 181 | SCOPED_LOCK(g_instanceLock); |
| @@ -178,6 +189,7 @@ MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, string *c | |||
| 178 | return kv; | 189 | return kv; |
| 179 | } | 190 | } |
| 180 | auto kv = new MMKV(mmapID, fd, metaFD, cryptKey); | 191 | auto kv = new MMKV(mmapID, fd, metaFD, cryptKey); |
| 192 | + kv->m_mmapKey = mmapID; | ||
| 181 | (*g_instanceDic)[mmapID] = kv; | 193 | (*g_instanceDic)[mmapID] = kv; |
| 182 | return kv; | 194 | return kv; |
| 183 | } | 195 | } |
| @@ -191,7 +203,7 @@ int MMKV::ashmemMetaFD() { | |||
| 191 | } | 203 | } |
| 192 | 204 | ||
| 193 | # ifndef MMKV_DISABLE_CRYPT | 205 | # ifndef MMKV_DISABLE_CRYPT |
| 194 | -void MMKV::checkReSetCryptKey(int fd, int metaFD, string *cryptKey) { | 206 | +void MMKV::checkReSetCryptKey(int fd, int metaFD, const string *cryptKey) { |
| 195 | SCOPED_LOCK(m_lock); | 207 | SCOPED_LOCK(m_lock); |
| 196 | 208 | ||
| 197 | checkReSetCryptKey(cryptKey); | 209 | checkReSetCryptKey(cryptKey); |
| @@ -1526,7 +1526,15 @@ bool MMKV::isFileValid(const string &mmapID, MMKVPath_t *relatePath) { | |||
| 1526 | bool MMKV::removeStorage(const std::string &mmapID, MMKVPath_t *relatePath) { | 1526 | bool MMKV::removeStorage(const std::string &mmapID, MMKVPath_t *relatePath) { |
| 1527 | auto mmapKey = mmapedKVKey(mmapID, relatePath); | 1527 | auto mmapKey = mmapedKVKey(mmapID, relatePath); |
| 1528 | #ifdef MMKV_ANDROID | 1528 | #ifdef MMKV_ANDROID |
| 1529 | - auto &realID = mmapKey; // historically Android mistakenly use mmapKey as mmapID | 1529 | + std::string realID; |
| 1530 | + auto correctPath = mappedKVPathWithID(mmapID, MMKV_SINGLE_PROCESS, relatePath); | ||
| 1531 | + if (relatePath && isFileExist(correctPath)) { | ||
| 1532 | + // it's successfully migrated to the correct path by newer version of MMKV | ||
| 1533 | + realID = mmapID; | ||
| 1534 | + } else { | ||
| 1535 | + // historically Android mistakenly use mmapKey as mmapID | ||
| 1536 | + realID = mmapKey; | ||
| 1537 | + } | ||
| 1530 | #else | 1538 | #else |
| 1531 | auto &realID = mmapID; | 1539 | auto &realID = mmapID; |
| 1532 | #endif | 1540 | #endif |
| @@ -1700,6 +1708,14 @@ bool MMKV::disableAutoKeyExpire() { | |||
| 1700 | MMKVVector vec; | 1708 | MMKVVector vec; |
| 1701 | auto packKeyValue = [&](const MMKVKey_t &key, const MMBuffer &value) { | 1709 | auto packKeyValue = [&](const MMKVKey_t &key, const MMBuffer &value) { |
| 1702 | assert(value.length() >= Fixed32Size); | 1710 | assert(value.length() >= Fixed32Size); |
| 1711 | + if (value.length() < Fixed32Size) { | ||
| 1712 | +#ifdef MMKV_APPLE | ||
| 1713 | + MMKVWarning("key [%@] has invalid value size %u", key, value.length()); | ||
| 1714 | +#else | ||
| 1715 | + MMKVWarning("key [%s] has invalid value size %u", key.data(), value.length()); | ||
| 1716 | +#endif | ||
| 1717 | + return; | ||
| 1718 | + } | ||
| 1703 | MMBuffer data(value.length() - Fixed32Size); | 1719 | MMBuffer data(value.length() - Fixed32Size); |
| 1704 | auto ptr = (uint8_t *) data.getPtr(); | 1720 | auto ptr = (uint8_t *) data.getPtr(); |
| 1705 | memcpy(ptr, value.getPtr(), value.length() - Fixed32Size); | 1721 | memcpy(ptr, value.getPtr(), value.length() - Fixed32Size); |
| @@ -1740,6 +1756,13 @@ uint32_t MMKV::getExpireTimeForKey(MMKVKey_t key) { | |||
| 1740 | auto raw = getRawDataForKey(key); | 1756 | auto raw = getRawDataForKey(key); |
| 1741 | assert(raw.length() == 0 || raw.length() >= Fixed32Size); | 1757 | assert(raw.length() == 0 || raw.length() >= Fixed32Size); |
| 1742 | if (raw.length() < Fixed32Size) { | 1758 | if (raw.length() < Fixed32Size) { |
| 1759 | + if (raw.length() != 0) { | ||
| 1760 | +#ifdef MMKV_APPLE | ||
| 1761 | + MMKVWarning("key [%@] has invalid value size %u", key, raw.length()); | ||
| 1762 | +#else | ||
| 1763 | + MMKVWarning("key [%s] has invalid value size %u", key.data(), raw.length()); | ||
| 1764 | +#endif | ||
| 1765 | + } | ||
| 1743 | return 0; | 1766 | return 0; |
| 1744 | } | 1767 | } |
| 1745 | auto ptr = (const uint8_t *) raw.getPtr() + raw.length() - Fixed32Size; | 1768 | auto ptr = (const uint8_t *) raw.getPtr() + raw.length() - Fixed32Size; |
| @@ -1755,6 +1778,13 @@ mmkv::MMBuffer MMKV::getDataWithoutMTimeForKey(MMKVKey_t key) { | |||
| 1755 | auto raw = getRawDataForKey(key); | 1778 | auto raw = getRawDataForKey(key); |
| 1756 | assert(raw.length() == 0 || raw.length() >= Fixed32Size); | 1779 | assert(raw.length() == 0 || raw.length() >= Fixed32Size); |
| 1757 | if (raw.length() < Fixed32Size) { | 1780 | if (raw.length() < Fixed32Size) { |
| 1781 | + if (raw.length() != 0) { | ||
| 1782 | +#ifdef MMKV_APPLE | ||
| 1783 | + MMKVWarning("key [%@] has invalid value size %u", key, raw.length()); | ||
| 1784 | +#else | ||
| 1785 | + MMKVWarning("key [%s] has invalid value size %u", key.data(), raw.length()); | ||
| 1786 | +#endif | ||
| 1787 | + } | ||
| 1758 | return raw; | 1788 | return raw; |
| 1759 | } | 1789 | } |
| 1760 | auto newLength = raw.length() - Fixed32Size; | 1790 | auto newLength = raw.length() - Fixed32Size; |
| @@ -1793,6 +1823,15 @@ size_t MMKV::filterExpiredKeys() { | |||
| 1793 | for (auto itr = m_dicCrypt->begin(); itr != m_dicCrypt->end(); NOOP) { | 1823 | for (auto itr = m_dicCrypt->begin(); itr != m_dicCrypt->end(); NOOP) { |
| 1794 | auto &kvHolder = itr->second; | 1824 | auto &kvHolder = itr->second; |
| 1795 | assert(kvHolder.realValueSize() >= Fixed32Size); | 1825 | assert(kvHolder.realValueSize() >= Fixed32Size); |
| 1826 | + if (kvHolder.realValueSize() < Fixed32Size) { | ||
| 1827 | +#ifdef MMKV_APPLE | ||
| 1828 | + MMKVWarning("key [%@] has invalid value size %u", itr->first, kvHolder.realValueSize()); | ||
| 1829 | +#else | ||
| 1830 | + MMKVWarning("key [%s] has invalid value size %u", itr->first.c_str(), kvHolder.realValueSize()); | ||
| 1831 | +#endif | ||
| 1832 | + itr++; | ||
| 1833 | + continue; | ||
| 1834 | + } | ||
| 1796 | auto buffer = kvHolder.toMMBuffer(basePtr, m_crypter); | 1835 | auto buffer = kvHolder.toMMBuffer(basePtr, m_crypter); |
| 1797 | auto ptr = (uint8_t *) buffer.getPtr(); | 1836 | auto ptr = (uint8_t *) buffer.getPtr(); |
| 1798 | ptr += buffer.length() - Fixed32Size; | 1837 | ptr += buffer.length() - Fixed32Size; |
| @@ -1817,6 +1856,15 @@ size_t MMKV::filterExpiredKeys() { | |||
| 1817 | for (auto itr = m_dic->begin(); itr != m_dic->end(); NOOP) { | 1856 | for (auto itr = m_dic->begin(); itr != m_dic->end(); NOOP) { |
| 1818 | auto &kvHolder = itr->second; | 1857 | auto &kvHolder = itr->second; |
| 1819 | assert(kvHolder.valueSize >= Fixed32Size); | 1858 | assert(kvHolder.valueSize >= Fixed32Size); |
| 1859 | + if (kvHolder.valueSize < Fixed32Size) { | ||
| 1860 | +#ifdef MMKV_APPLE | ||
| 1861 | + MMKVWarning("key [%@] has invalid value size %u", itr->first, kvHolder.valueSize); | ||
| 1862 | +#else | ||
| 1863 | + MMKVWarning("key [%s] has invalid value size %u", itr->first.c_str(), kvHolder.valueSize); | ||
| 1864 | +#endif | ||
| 1865 | + itr++; | ||
| 1866 | + continue; | ||
| 1867 | + } | ||
| 1820 | auto ptr = basePtr + kvHolder.offset + kvHolder.computedKVSize; | 1868 | auto ptr = basePtr + kvHolder.offset + kvHolder.computedKVSize; |
| 1821 | ptr += kvHolder.valueSize - Fixed32Size; | 1869 | ptr += kvHolder.valueSize - Fixed32Size; |
| 1822 | auto time = *(const uint32_t *) ptr; | 1870 | auto time = *(const uint32_t *) ptr; |
| @@ -506,6 +506,13 @@ bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { | |||
| 506 | if (copyFileContent(srcPath, tmpFD, false)) { | 506 | if (copyFileContent(srcPath, tmpFD, false)) { |
| 507 | MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpPath.c_str()); | 507 | MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpPath.c_str()); |
| 508 | renamed = tryAtomicRename(tmpPath, dstPath); | 508 | renamed = tryAtomicRename(tmpPath, dstPath); |
| 509 | + if (!renamed) { | ||
| 510 | + MMKVInfo("rename fail, try copy file content instead."); | ||
| 511 | + if (copyFileContent(tmpPath, dstPath)) { | ||
| 512 | + renamed = true; | ||
| 513 | + ::unlink(tmpPath.c_str()); | ||
| 514 | + } | ||
| 515 | + } | ||
| 509 | if (renamed) { | 516 | if (renamed) { |
| 510 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); | 517 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); |
| 511 | } | 518 | } |
| @@ -72,6 +72,10 @@ bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { | |||
| 72 | MMKVWarning("fail on syscall(SYS_renameat2) [%s] to [%s], %d(%s)", srcPath.c_str(), dstPath.c_str(), errno, | 72 | MMKVWarning("fail on syscall(SYS_renameat2) [%s] to [%s], %d(%s)", srcPath.c_str(), dstPath.c_str(), errno, |
| 73 | strerror(errno)); | 73 | strerror(errno)); |
| 74 | } | 74 | } |
| 75 | + | ||
| 76 | + if (renamed && (srcPath != dstPath)) { | ||
| 77 | + ::unlink(srcPath.c_str()); | ||
| 78 | + } | ||
| 75 | #endif // SYS_renameat2 && !MMKV_OHOS | 79 | #endif // SYS_renameat2 && !MMKV_OHOS |
| 76 | 80 | ||
| 77 | if (!renamed) { | 81 | if (!renamed) { |
| @@ -81,7 +85,6 @@ bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { | |||
| 81 | } | 85 | } |
| 82 | } | 86 | } |
| 83 | 87 | ||
| 84 | - ::unlink(srcPath.c_str()); | ||
| 85 | return true; | 88 | return true; |
| 86 | } | 89 | } |
| 87 | 90 | ||
| @@ -58,6 +58,9 @@ void tryResetFileProtection(const string &path) { | |||
| 58 | namespace mmkv { | 58 | namespace mmkv { |
| 59 | 59 | ||
| 60 | bool tryAtomicRename(const char *src, const char *dst) { | 60 | bool tryAtomicRename(const char *src, const char *dst) { |
| 61 | + if (!src || !dst) { | ||
| 62 | + return false; | ||
| 63 | + } | ||
| 61 | bool renamed = false; | 64 | bool renamed = false; |
| 62 | 65 | ||
| 63 | // try atomic swap first | 66 | // try atomic swap first |
| @@ -65,6 +68,9 @@ bool tryAtomicRename(const char *src, const char *dst) { | |||
| 65 | // renameat2() equivalent | 68 | // renameat2() equivalent |
| 66 | if (renamex_np(src, dst, RENAME_SWAP) == 0) { | 69 | if (renamex_np(src, dst, RENAME_SWAP) == 0) { |
| 67 | renamed = true; | 70 | renamed = true; |
| 71 | + if (strcmp(src, dst) != 0) { | ||
| 72 | + ::unlink(src); | ||
| 73 | + } | ||
| 68 | } else if (errno != ENOENT) { | 74 | } else if (errno != ENOENT) { |
| 69 | MMKVError("fail to renamex_np %s to %s, %s", src, dst, strerror(errno)); | 75 | MMKVError("fail to renamex_np %s to %s, %s", src, dst, strerror(errno)); |
| 70 | } | 76 | } |
| @@ -78,8 +84,6 @@ bool tryAtomicRename(const char *src, const char *dst) { | |||
| 78 | } | 84 | } |
| 79 | } | 85 | } |
| 80 | 86 | ||
| 81 | - ::unlink(src); | ||
| 82 | - | ||
| 83 | return true; | 87 | return true; |
| 84 | } | 88 | } |
| 85 | 89 | ||
| @@ -97,8 +101,12 @@ bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { | |||
| 97 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); | 101 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); |
| 98 | return true; | 102 | return true; |
| 99 | } | 103 | } |
| 104 | + | ||
| 105 | + MMKVInfo("rename fail, try copy file content instead."); | ||
| 106 | + auto ret = copyFileContent(tmpFile.UTF8String, dstPath); | ||
| 107 | + | ||
| 100 | unlink(tmpFile.UTF8String); | 108 | unlink(tmpFile.UTF8String); |
| 101 | - return false; | 109 | + return ret; |
| 102 | } | 110 | } |
| 103 | 111 | ||
| 104 | bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { | 112 | bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { |
| @@ -24,13 +24,28 @@ | |||
| 24 | #include <cstdlib> | 24 | #include <cstdlib> |
| 25 | #include <cstring> | 25 | #include <cstring> |
| 26 | #include <ctime> | 26 | #include <ctime> |
| 27 | +#include "../MMKVLog.h" | ||
| 28 | +#include "../MemoryFile.h" | ||
| 29 | + | ||
| 30 | +namespace mmkv { | ||
| 31 | + | ||
| 32 | +// assuming size in [1, 5] | ||
| 33 | +uint32_t AESCrypt::randomItemSizeHolder(uint32_t size) { | ||
| 34 | + constexpr uint32_t ItemSizeHolders[] = {0, 0x80, 0x4000, 0x200000, 0x10000000, 0}; | ||
| 35 | + auto ItemSizeHolderMin = ItemSizeHolders[size - 1]; | ||
| 36 | + auto ItemSizeHolderMax = ItemSizeHolders[size] - 1; | ||
| 37 | + | ||
| 38 | + srand((unsigned) time(nullptr)); | ||
| 39 | + auto result = static_cast<uint32_t>(rand()); | ||
| 40 | + result = result % (ItemSizeHolderMax - ItemSizeHolderMin + 1); | ||
| 41 | + result += ItemSizeHolderMin; | ||
| 42 | + return result; | ||
| 43 | +} | ||
| 27 | 44 | ||
| 28 | #ifndef MMKV_DISABLE_CRYPT | 45 | #ifndef MMKV_DISABLE_CRYPT |
| 29 | 46 | ||
| 30 | using namespace openssl; | 47 | using namespace openssl; |
| 31 | 48 | ||
| 32 | -namespace mmkv { | ||
| 33 | - | ||
| 34 | AESCrypt::AESCrypt(const void *key, size_t keyLength, const void *iv, size_t ivLength) { | 49 | AESCrypt::AESCrypt(const void *key, size_t keyLength, const void *iv, size_t ivLength) { |
| 35 | if (key && keyLength > 0) { | 50 | if (key && keyLength > 0) { |
| 36 | memcpy(m_key, key, (keyLength > AES_KEY_LEN) ? AES_KEY_LEN : keyLength); | 51 | memcpy(m_key, key, (keyLength > AES_KEY_LEN) ? AES_KEY_LEN : keyLength); |
| @@ -102,19 +117,6 @@ void AESCrypt::fillRandomIV(void *vector) { | |||
| 102 | } | 117 | } |
| 103 | } | 118 | } |
| 104 | 119 | ||
| 105 | -// assuming size in [1, 5] | ||
| 106 | -uint32_t AESCrypt::randomItemSizeHolder(uint32_t size) { | ||
| 107 | - constexpr uint32_t ItemSizeHolders[] = {0, 0x80, 0x4000, 0x200000, 0x10000000, 0}; | ||
| 108 | - auto ItemSizeHolderMin = ItemSizeHolders[size - 1]; | ||
| 109 | - auto ItemSizeHolderMax = ItemSizeHolders[size] - 1; | ||
| 110 | - | ||
| 111 | - srand((unsigned) time(nullptr)); | ||
| 112 | - auto result = static_cast<uint32_t>(rand()); | ||
| 113 | - result = result % (ItemSizeHolderMax - ItemSizeHolderMin + 1); | ||
| 114 | - result += ItemSizeHolderMin; | ||
| 115 | - return result; | ||
| 116 | -} | ||
| 117 | - | ||
| 118 | static inline void | 120 | static inline void |
| 119 | Rollback_cfb_decrypt(const uint8_t *input, const uint8_t *output, size_t len, AES_KEY *key, AESCryptStatus &status) { | 121 | Rollback_cfb_decrypt(const uint8_t *input, const uint8_t *output, size_t len, AES_KEY *key, AESCryptStatus &status) { |
| 120 | auto ivec = status.m_vector; | 122 | auto ivec = status.m_vector; |
| @@ -174,15 +176,8 @@ AESCrypt AESCrypt::cloneWithStatus(const AESCryptStatus &status) const { | |||
| 174 | return AESCrypt(*this, status); | 176 | return AESCrypt(*this, status); |
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | -} // namespace mmkv | ||
| 178 | - | ||
| 179 | # ifdef MMKV_DEBUG | 179 | # ifdef MMKV_DEBUG |
| 180 | 180 | ||
| 181 | -# include "../MMKVLog.h" | ||
| 182 | -# include "../MemoryFile.h" | ||
| 183 | - | ||
| 184 | -namespace mmkv { | ||
| 185 | - | ||
| 186 | void testRandomPlaceHolder() { | 181 | void testRandomPlaceHolder() { |
| 187 | for (uint32_t size = 1; size < 6; size++) { | 182 | for (uint32_t size = 1; size < 6; size++) { |
| 188 | auto holder = AESCrypt::randomItemSizeHolder(size); | 183 | auto holder = AESCrypt::randomItemSizeHolder(size); |
| @@ -272,7 +267,7 @@ void AESCrypt::testAESCrypt() { | |||
| 272 | delete[] decryptText; | 267 | delete[] decryptText; |
| 273 | } | 268 | } |
| 274 | 269 | ||
| 275 | -} // namespace mmkv | ||
| 276 | - | ||
| 277 | # endif // MMKV_DEBUG | 270 | # endif // MMKV_DEBUG |
| 278 | #endif // MMKV_DISABLE_CRYPT | 271 | #endif // MMKV_DISABLE_CRYPT |
| 272 | + | ||
| 273 | +} // namespace mmkv | ||
| @@ -29,7 +29,10 @@ | |||
| 29 | #ifdef MMKV_DISABLE_CRYPT | 29 | #ifdef MMKV_DISABLE_CRYPT |
| 30 | 30 | ||
| 31 | namespace mmkv { | 31 | namespace mmkv { |
| 32 | -class AESCrypt; | 32 | +class AESCrypt { |
| 33 | +public: | ||
| 34 | + static uint32_t randomItemSizeHolder(uint32_t size); | ||
| 35 | +}; | ||
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | #else | 38 | #else |
| @@ -1 +1 @@ | |||
| 1 | -{"version":3,"file":"memoryStore.d.ts","sourceRoot":"","sources":["../../memoryStore.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,MAAM,QAAO,OAMzB,CAAC;AAEF,eAAO,MAAM,IAAI,QAAO,OAqKvB,CAAC"} | 1 | +{"version":3,"file":"memoryStore.d.ts","sourceRoot":"","sources":["../../memoryStore.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,MAAM,QAAO,OAMzB,CAAC;AAEF,eAAO,MAAM,IAAI,QAAO,OA4KvB,CAAC"} |
| @@ -96,7 +96,7 @@ export var mock = function () { | |||
| 96 | if (!MEMORY_STORE[id]) | 96 | if (!MEMORY_STORE[id]) |
| 97 | return undefined; | 97 | return undefined; |
| 98 | var value = MEMORY_STORE[id].storage[key]; | 98 | var value = MEMORY_STORE[id].storage[key]; |
| 99 | - if (!value) | 99 | + if (typeof value != 'string') |
| 100 | return null; | 100 | return null; |
| 101 | return value; | 101 | return value; |
| 102 | }; | 102 | }; |
| @@ -111,7 +111,7 @@ export var mock = function () { | |||
| 111 | if (!MEMORY_STORE[id]) | 111 | if (!MEMORY_STORE[id]) |
| 112 | return undefined; | 112 | return undefined; |
| 113 | var value = MEMORY_STORE[id].storage[key]; | 113 | var value = MEMORY_STORE[id].storage[key]; |
| 114 | - if (!value) | 114 | + if (typeof value != 'number') |
| 115 | return null; | 115 | return null; |
| 116 | return value; | 116 | return value; |
| 117 | }; | 117 | }; |
| @@ -126,7 +126,7 @@ export var mock = function () { | |||
| 126 | if (!MEMORY_STORE[id]) | 126 | if (!MEMORY_STORE[id]) |
| 127 | return undefined; | 127 | return undefined; |
| 128 | var value = MEMORY_STORE[id].storage[key]; | 128 | var value = MEMORY_STORE[id].storage[key]; |
| 129 | - if (!value) | 129 | + if (typeof value != 'boolean') |
| 130 | return null; | 130 | return null; |
| 131 | return value; | 131 | return value; |
| 132 | }; | 132 | }; |
| @@ -165,6 +165,14 @@ export var mock = function () { | |||
| 165 | return undefined; | 165 | return undefined; |
| 166 | return Object.keys(MEMORY_STORE[id].storage); | 166 | return Object.keys(MEMORY_STORE[id].storage); |
| 167 | }; | 167 | }; |
| 168 | + mmkvJsiModule.removeValuesMMKV = function (keys, id) { | ||
| 169 | + if (!MEMORY_STORE[id]) | ||
| 170 | + return undefined; | ||
| 171 | + for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { | ||
| 172 | + var key = keys_1[_i]; | ||
| 173 | + mmkvJsiModule.removeValueMMKV(key, id); | ||
| 174 | + } | ||
| 175 | + }; | ||
| 168 | mmkvJsiModule.setupMMKVInstance('mmkvIdStore'); | 176 | mmkvJsiModule.setupMMKVInstance('mmkvIdStore'); |
| 169 | return true; | 177 | return true; |
| 170 | }; | 178 | }; |
| @@ -0,0 +1,201 @@ | |||
| 1 | +import { MMKVJsiModule, IndexType } from '../src/types/index'; | ||
| 2 | + | ||
| 3 | +type MemoryStore = { | ||
| 4 | + [name: string]: { | ||
| 5 | + indexes: { | ||
| 6 | + stringIndex: string[]; | ||
| 7 | + boolIndex: string[]; | ||
| 8 | + numberIndex: string[]; | ||
| 9 | + mapIndex: string[]; | ||
| 10 | + arrayIndex: string[]; | ||
| 11 | + }; | ||
| 12 | + storage: { [name: string]: any }; | ||
| 13 | + }; | ||
| 14 | +}; | ||
| 15 | +//@ts-ignore | ||
| 16 | +const mmkvJsiModule: MMKVJsiModule = global; | ||
| 17 | + | ||
| 18 | +let SECURE_KEYSTORE: { [name: string]: string | null } = {}; | ||
| 19 | +let MEMORY_STORE: MemoryStore = {}; | ||
| 20 | + | ||
| 21 | +export const unmock = (): boolean => { | ||
| 22 | + //@ts-ignore | ||
| 23 | + mmkvJsiModule.getStringMMKV = undefined; | ||
| 24 | + SECURE_KEYSTORE = {}; | ||
| 25 | + MEMORY_STORE = {}; | ||
| 26 | + return true; | ||
| 27 | +}; | ||
| 28 | + | ||
| 29 | +export const mock = (): boolean => { | ||
| 30 | + SECURE_KEYSTORE = {}; | ||
| 31 | + MEMORY_STORE = {}; | ||
| 32 | + mmkvJsiModule.setupMMKVInstance = id => { | ||
| 33 | + MEMORY_STORE[id] = { | ||
| 34 | + indexes: { | ||
| 35 | + stringIndex: [], | ||
| 36 | + boolIndex: [], | ||
| 37 | + numberIndex: [], | ||
| 38 | + mapIndex: [], | ||
| 39 | + arrayIndex: [] | ||
| 40 | + }, | ||
| 41 | + storage: {} | ||
| 42 | + }; | ||
| 43 | + return true; | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + //@ts-ignore | ||
| 47 | + mmkvJsiModule.setMMKVServiceName = (alias, serviceName) => { | ||
| 48 | + return serviceName; | ||
| 49 | + }; | ||
| 50 | + | ||
| 51 | + mmkvJsiModule.getSecureKey = alias => { | ||
| 52 | + return SECURE_KEYSTORE[alias]; | ||
| 53 | + }; | ||
| 54 | + | ||
| 55 | + mmkvJsiModule.setSecureKey = (alias, key) => { | ||
| 56 | + SECURE_KEYSTORE[alias] = key; | ||
| 57 | + return true; | ||
| 58 | + }; | ||
| 59 | + | ||
| 60 | + mmkvJsiModule.secureKeyExists = alias => { | ||
| 61 | + return Object.keys(SECURE_KEYSTORE).includes(alias); | ||
| 62 | + }; | ||
| 63 | + | ||
| 64 | + mmkvJsiModule.removeSecureKey = alias => { | ||
| 65 | + delete SECURE_KEYSTORE[alias]; | ||
| 66 | + return true; | ||
| 67 | + }; | ||
| 68 | + | ||
| 69 | + mmkvJsiModule.clearMMKV = id => { | ||
| 70 | + mmkvJsiModule.setupMMKVInstance(id); | ||
| 71 | + return true; | ||
| 72 | + }; | ||
| 73 | + | ||
| 74 | + mmkvJsiModule.clearMemoryCache = () => { | ||
| 75 | + return true; | ||
| 76 | + }; | ||
| 77 | + mmkvJsiModule.decryptMMKV = () => { | ||
| 78 | + return true; | ||
| 79 | + }; | ||
| 80 | + | ||
| 81 | + mmkvJsiModule.encryptMMKV = () => { | ||
| 82 | + return true; | ||
| 83 | + }; | ||
| 84 | + | ||
| 85 | + mmkvJsiModule.containsKeyMMKV = (key, id) => { | ||
| 86 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 87 | + return Object.keys(MEMORY_STORE[id].storage).includes(key); | ||
| 88 | + }; | ||
| 89 | + | ||
| 90 | + mmkvJsiModule.getIndexMMKV = (type, id) => { | ||
| 91 | + if (!MEMORY_STORE[id]) return []; | ||
| 92 | + return MEMORY_STORE[id].indexes[type]; | ||
| 93 | + }; | ||
| 94 | + | ||
| 95 | + mmkvJsiModule.removeValueMMKV = (key, id) => { | ||
| 96 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 97 | + delete MEMORY_STORE[id].storage[key]; | ||
| 98 | + | ||
| 99 | + Object.keys(MEMORY_STORE[id].indexes).forEach(indexKey => { | ||
| 100 | + //@ts-ignore | ||
| 101 | + let index: string[] = MEMORY_STORE[id].indexes[indexKey]; | ||
| 102 | + if (index.includes(key)) { | ||
| 103 | + index.splice(index.indexOf(key), 1); | ||
| 104 | + } | ||
| 105 | + }); | ||
| 106 | + | ||
| 107 | + return true; | ||
| 108 | + }; | ||
| 109 | + | ||
| 110 | + const updateIndex = (key: string, indexType: IndexType, id: string) => { | ||
| 111 | + let index = MEMORY_STORE[id].indexes[indexType]; | ||
| 112 | + if (!index.includes(key)) { | ||
| 113 | + index.push(key); | ||
| 114 | + } | ||
| 115 | + }; | ||
| 116 | + | ||
| 117 | + mmkvJsiModule.setStringMMKV = (key, value, id) => { | ||
| 118 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 119 | + MEMORY_STORE[id].storage[key] = value; | ||
| 120 | + updateIndex(key, 'stringIndex', id); | ||
| 121 | + return true; | ||
| 122 | + }; | ||
| 123 | + | ||
| 124 | + mmkvJsiModule.getStringMMKV = (key, id) => { | ||
| 125 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 126 | + let value = MEMORY_STORE[id].storage[key]; | ||
| 127 | + if (typeof value != 'string') return null; | ||
| 128 | + return value; | ||
| 129 | + }; | ||
| 130 | + | ||
| 131 | + mmkvJsiModule.setNumberMMKV = (key, value, id) => { | ||
| 132 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 133 | + MEMORY_STORE[id].storage[key] = value; | ||
| 134 | + updateIndex(key, 'numberIndex', id); | ||
| 135 | + return true; | ||
| 136 | + }; | ||
| 137 | + | ||
| 138 | + mmkvJsiModule.getNumberMMKV = (key, id) => { | ||
| 139 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 140 | + let value = MEMORY_STORE[id].storage[key]; | ||
| 141 | + if (typeof value != 'number') return null; | ||
| 142 | + return value; | ||
| 143 | + }; | ||
| 144 | + | ||
| 145 | + mmkvJsiModule.setBoolMMKV = (key, value, id) => { | ||
| 146 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 147 | + MEMORY_STORE[id].storage[key] = value; | ||
| 148 | + updateIndex(key, 'boolIndex', id); | ||
| 149 | + return true; | ||
| 150 | + }; | ||
| 151 | + | ||
| 152 | + mmkvJsiModule.getBoolMMKV = (key, id) => { | ||
| 153 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 154 | + let value = MEMORY_STORE[id].storage[key]; | ||
| 155 | + if (typeof value != 'boolean') return null; | ||
| 156 | + return value; | ||
| 157 | + }; | ||
| 158 | + | ||
| 159 | + mmkvJsiModule.setMapMMKV = (key, value, id) => { | ||
| 160 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 161 | + MEMORY_STORE[id].storage[key] = value; | ||
| 162 | + updateIndex(key, 'mapIndex', id); | ||
| 163 | + return true; | ||
| 164 | + }; | ||
| 165 | + | ||
| 166 | + mmkvJsiModule.getMapMMKV = (key, id) => { | ||
| 167 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 168 | + let value = MEMORY_STORE[id].storage[key]; | ||
| 169 | + if (!value) return null; | ||
| 170 | + return value; | ||
| 171 | + }; | ||
| 172 | + | ||
| 173 | + mmkvJsiModule.setArrayMMKV = (key, value, id) => { | ||
| 174 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 175 | + MEMORY_STORE[id].storage[key] = value; | ||
| 176 | + updateIndex(key, 'arrayIndex', id); | ||
| 177 | + return true; | ||
| 178 | + }; | ||
| 179 | + | ||
| 180 | + mmkvJsiModule.getArrayMMKV = (key, id) => { | ||
| 181 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 182 | + let value = MEMORY_STORE[id].storage[key]; | ||
| 183 | + if (!value) return null; | ||
| 184 | + return value; | ||
| 185 | + }; | ||
| 186 | + | ||
| 187 | + mmkvJsiModule.getAllKeysMMKV = id => { | ||
| 188 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 189 | + return Object.keys(MEMORY_STORE[id].storage); | ||
| 190 | + }; | ||
| 191 | + | ||
| 192 | + mmkvJsiModule.removeValuesMMKV = (keys, id) => { | ||
| 193 | + if (!MEMORY_STORE[id]) return undefined; | ||
| 194 | + for (let key of keys) { | ||
| 195 | + mmkvJsiModule.removeValueMMKV(key, id); | ||
| 196 | + } | ||
| 197 | + }; | ||
| 198 | + | ||
| 199 | + mmkvJsiModule.setupMMKVInstance('mmkvIdStore'); | ||
| 200 | + return true; | ||
| 201 | +}; | ||
| @@ -2,12 +2,6 @@ if (!global.__fbBatchedBridgeConfig) { | |||
| 2 | global.__fbBatchedBridgeConfig = {}; | 2 | global.__fbBatchedBridgeConfig = {}; |
| 3 | } | 3 | } |
| 4 | 4 | ||
| 5 | -if (!global.__turboModuleProxy) { | ||
| 6 | - global.__turboModuleProxy = name => { | ||
| 7 | - return {}; | ||
| 8 | - }; | ||
| 9 | -} | ||
| 10 | - | ||
| 11 | require('react-native').NativeModules.MMKVNative = { | 5 | require('react-native').NativeModules.MMKVNative = { |
| 12 | install: jest.fn(() => true) | 6 | install: jest.fn(() => true) |
| 13 | }; | 7 | }; |
| @@ -0,0 +1,25 @@ | |||
| 1 | +{ | ||
| 2 | + "include": ["memoryStore.ts"], | ||
| 3 | + "compilerOptions": { | ||
| 4 | + "baseUrl": "./", | ||
| 5 | + "jsx": "react-native", | ||
| 6 | + "module": "esnext", | ||
| 7 | + "moduleResolution": "node", | ||
| 8 | + "lib": ["es2017"], | ||
| 9 | + "declaration": true, | ||
| 10 | + "declarationMap": true, | ||
| 11 | + "outDir": "dist", | ||
| 12 | + "allowSyntheticDefaultImports": true, | ||
| 13 | + "esModuleInterop": true, | ||
| 14 | + "forceConsistentCasingInFileNames": true, | ||
| 15 | + "noFallthroughCasesInSwitch": true, | ||
| 16 | + "noImplicitReturns": true, | ||
| 17 | + "noUnusedLocals": true, | ||
| 18 | + "noUnusedParameters": true, | ||
| 19 | + "pretty": true, | ||
| 20 | + "resolveJsonModule": true, | ||
| 21 | + "skipLibCheck": true, | ||
| 22 | + "strict": true, | ||
| 23 | + "allowJs": true | ||
| 24 | + } | ||
| 25 | +} | ||
| @@ -8,9 +8,6 @@ | |||
| 8 | "build": "tsc", | 8 | "build": "tsc", |
| 9 | "watch": "tsc --watch" | 9 | "watch": "tsc --watch" |
| 10 | }, | 10 | }, |
| 11 | - "bin": { | ||
| 12 | - "mmkv-link": "./autolink/postlink/run.js" | ||
| 13 | - }, | ||
| 14 | "files": [ | 11 | "files": [ |
| 15 | "jest", | 12 | "jest", |
| 16 | "MMKV", | 13 | "MMKV", |
| @@ -58,21 +55,23 @@ | |||
| 58 | "devDependencies": { | 55 | "devDependencies": { |
| 59 | "@babel/core": "^7.26.0", | 56 | "@babel/core": "^7.26.0", |
| 60 | "@babel/runtime": "^7.26.0", | 57 | "@babel/runtime": "^7.26.0", |
| 61 | - "@types/react": "18.3.1", | 58 | + "@types/react": "^19.0.0", |
| 62 | "@types/react-native": "0.73.0", | 59 | "@types/react-native": "0.73.0", |
| 63 | - "babel-jest": "^29.6.3", | 60 | + "@react-native-community/cli": "18.0.0", |
| 64 | - "babel-plugin-module-resolver": "^5.0.0", | 61 | + "@react-native/babel-preset": "0.79.5", |
| 62 | + "@react-native/eslint-config": "0.79.5", | ||
| 63 | + "@react-native/metro-config": "0.79.5", | ||
| 64 | + "@react-native/typescript-config": "0.79.5", | ||
| 65 | + "metro": "0.82.0", | ||
| 65 | "jest": "^29.2.1", | 66 | "jest": "^29.2.1", |
| 66 | - "metro": "0.76.1", | 67 | + "react": "19.0.0", |
| 67 | - "metro-react-native-babel-preset": "0.76.1", | 68 | + "react-native": "0.79.5", |
| 68 | - "react": "18.3.1", | ||
| 69 | - "react-native": "0.77.1", | ||
| 70 | "typescript": "^5.1.6", | 69 | "typescript": "^5.1.6", |
| 71 | "eslint": "^8.57.1", | 70 | "eslint": "^8.57.1", |
| 72 | "@react-native-community/eslint-config": "^3.2.0" | 71 | "@react-native-community/eslint-config": "^3.2.0" |
| 73 | }, | 72 | }, |
| 74 | "dependencies": { | 73 | "dependencies": { |
| 75 | - "react-native-mmkv-storage": "0.11.2" | 74 | + "react-native-mmkv-storage": "12.0.1" |
| 76 | }, | 75 | }, |
| 77 | "harmony": { | 76 | "harmony": { |
| 78 | "alias": "react-native-mmkv-storage" | 77 | "alias": "react-native-mmkv-storage" |
| @@ -99,7 +99,7 @@ export type MMKVJsiModule = { | |||
| 99 | getBoolMMKV: (key: string, id: string) => boolean | null | undefined; | 99 | getBoolMMKV: (key: string, id: string) => boolean | null | undefined; |
| 100 | 100 | ||
| 101 | removeValueMMKV: (key: string, id: string) => boolean | undefined; | 101 | removeValueMMKV: (key: string, id: string) => boolean | undefined; |
| 102 | - removeValuesMMKV: (...keys: string[]) => boolean | undefined; | 102 | + removeValuesMMKV: (keys: string[], id: string) => boolean | undefined; |
| 103 | 103 | ||
| 104 | getAllKeysMMKV: (id: string) => string[] | undefined; | 104 | getAllKeysMMKV: (id: string) => string[] | undefined; |
| 105 | getIndexMMKV: (type: IndexType, id: string) => string[] | undefined; | 105 | getIndexMMKV: (type: IndexType, id: string) => string[] | undefined; |