1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef OHOS_KV_STORE_H
16 #define OHOS_KV_STORE_H
17 #include <mutex>
18 #include <memory>
19 #include "napi_queue.h"
20 #include "single_kvstore.h"
21 #include "uv_queue.h"
22 #include "js_observer.h"
23 #include "js_kv_manager.h"
24 
25 namespace OHOS::DistributedData {
26 enum {
27     /* exported js SubscribeType  is (DistributedKv::SubscribeType-1) */
28     SUBSCRIBE_LOCAL = 0,        /* i.e. SubscribeType::SUBSCRIBE_TYPE_LOCAL-1  */
29     SUBSCRIBE_REMOTE = 1,       /* i.e. SubscribeType::SUBSCRIBE_TYPE_REMOTE-1 */
30     SUBSCRIBE_LOCAL_REMOTE = 2, /* i.e. SubscribeType::SUBSCRIBE_TYPE_ALL-1   */
31     SUBSCRIBE_COUNT = 3
32 };
33 /* [NOTES]
34  *    OHOS::DistributedData::JsKVStore is NOT related to DistributedKv::KvStore!!!
35  *    OHOS::DistributedData::JsKVStore is wrapped for DistributedKv::SingleKvStore...
36  */
37 class JsKVStore {
38 public:
39     explicit JsKVStore(const std::string& storeId);
40     virtual ~JsKVStore();
41 
42     void SetNative(std::shared_ptr<DistributedKv::SingleKvStore>& kvStore);
43     void SetSchemaInfo(bool isSchemaStore);
44     void SetUvQueue(std::shared_ptr<UvQueue> uvQueue);
45     std::shared_ptr<DistributedKv::SingleKvStore>& GetNative();
46     void SetContextParam(std::shared_ptr<ContextParam> param);
47     static bool IsInstanceOf(napi_env env, napi_value obj, const std::string& storeId, napi_value constructor);
48 
49     /* public static members */
50     static napi_value Put(napi_env env, napi_callback_info info);
51     static napi_value Delete(napi_env env, napi_callback_info info);
52     static napi_value OnEvent(napi_env env, napi_callback_info info);
53     static napi_value OffEvent(napi_env env, napi_callback_info info);
54     static napi_value PutBatch(napi_env env, napi_callback_info info);
55     static napi_value DeleteBatch(napi_env env, napi_callback_info info);
56     static napi_value StartTransaction(napi_env env, napi_callback_info info);
57     static napi_value Commit(napi_env env, napi_callback_info info);
58     static napi_value Rollback(napi_env env, napi_callback_info info);
59     static napi_value EnableSync(napi_env env, napi_callback_info info);
60     static napi_value SetSyncRange(napi_env env, napi_callback_info info);
61 
62 protected:
63     bool IsSchemaStore() const;
64 private:
65     class DataObserver : public DistributedKv::KvStoreObserver, public JSObserver {
66     public:
DataObserver(std::shared_ptr<UvQueue> uvQueue,napi_value callback,bool schema)67         DataObserver(std::shared_ptr<UvQueue> uvQueue, napi_value callback, bool schema)
68             : JSObserver(uvQueue, callback), isSchema_(schema){};
69         virtual ~DataObserver() = default;
70         void OnChange(const DistributedKv::ChangeNotification& notification) override;
71 
72     private:
73         bool isSchema_ = false;
74     };
75 
76     class SyncObserver : public DistributedKv::KvStoreSyncCallback, public JSObserver {
77     public:
SyncObserver(std::shared_ptr<UvQueue> uvQueue,napi_value callback)78         SyncObserver(std::shared_ptr<UvQueue> uvQueue, napi_value callback) : JSObserver(uvQueue, callback) {};
79         virtual ~SyncObserver() = default;
80         void SyncCompleted(const std::map<std::string, DistributedKv::Status>& results) override;
81     };
82 
83     /* private static members */
84     static void OnDataChange(napi_env env, size_t argc, napi_value* argv, std::shared_ptr<ContextBase> ctxt);
85     static void OffDataChange(napi_env env, size_t argc, napi_value* argv, std::shared_ptr<ContextBase> ctxt);
86 
87     static void OnSyncComplete(napi_env env, size_t argc, napi_value* argv, std::shared_ptr<ContextBase> ctxt);
88     static void OffSyncComplete(napi_env env, size_t argc, napi_value* argv, std::shared_ptr<ContextBase> ctxt);
89 
90     /* private non-static members */
91     napi_status Subscribe(uint8_t type, std::shared_ptr<DataObserver> observer);
92     napi_status UnSubscribe(uint8_t type, std::shared_ptr<DataObserver> observer);
93 
94     napi_status RegisterSyncCallback(std::shared_ptr<SyncObserver> sync);
95     napi_status UnRegisterSyncCallback();
96 
97     /* private non-static members */
98     std::shared_ptr<DistributedKv::SingleKvStore> kvStore_ = nullptr;
99     std::string storeId_;
100     std::shared_ptr<ContextParam> param_ = nullptr;
101     bool isSchemaStore_ = false;
102 
103     using Exec = std::function<void(napi_env, size_t, napi_value*, std::shared_ptr<ContextBase>)>;
104     static std::map<std::string, Exec> onEventHandlers_;
105     static std::map<std::string, Exec> offEventHandlers_;
106 
107     std::list<std::shared_ptr<SyncObserver>> syncObservers_;
108     std::mutex listMutex_ {};
109     std::list<std::shared_ptr<DataObserver>> dataObserver_[SUBSCRIBE_COUNT];
110     std::shared_ptr<UvQueue> uvQueue_;
111 };
112 } // namespace OHOS::DistributedData
113 #endif // OHOS_KV_STORE_H
114