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 
16 #ifndef NATIVE_RDB_SQLITE_CONNECTION_H
17 #define NATIVE_RDB_SQLITE_CONNECTION_H
18 
19 #include <atomic>
20 #include <cstdint>
21 #include <list>
22 #include <memory>
23 #include <mutex>
24 #include <vector>
25 
26 #include "connection.h"
27 #include "rdb_local_db_observer.h"
28 #include "rdb_store_config.h"
29 #include "sqlite3sym.h"
30 #include "sqlite_statement.h"
31 #include "value_object.h"
32 
33 typedef struct ClientChangedData ClientChangedData;
34 namespace OHOS {
35 namespace NativeRdb {
36 /**
37  * @brief Use DataChangeCallback replace std::function<void(ClientChangedData &clientChangedData)>.
38  */
39 using DataChangeCallback = std::function<void(ClientChangedData &clientChangedData)>;
40 
41 class SqliteConnection : public Connection {
42 public:
43     static std::pair<int32_t, std::shared_ptr<Connection>> Create(const RdbStoreConfig &config, bool isWrite);
44     static int32_t Delete(const RdbStoreConfig &config);
45     static int32_t Repair(const RdbStoreConfig &config);
46     static std::map<std::string, Info> Collect(const RdbStoreConfig &config);
47     SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection);
48     ~SqliteConnection();
49     int32_t OnInitialize() override;
50     int TryCheckPoint(bool timeout) override;
51     int LimitWalSize() override;
52     int ConfigLocale(const std::string &localeStr) override;
53     int CleanDirtyData(const std::string &table, uint64_t cursor) override;
54     int ReSetKey(const RdbStoreConfig &config) override;
55     int32_t GetJournalMode() override;
56     std::pair<int32_t, Stmt> CreateStatement(const std::string &sql, SConn conn) override;
57     bool IsWriter() const override;
58     int SubscribeTableChanges(const Notifier &notifier) override;
59     int GetMaxVariable() const override;
60     int32_t GetDBType() const override;
61     int32_t ClearCache() override;
62     int32_t Subscribe(const std::string &event,
63         const std::shared_ptr<DistributedRdb::RdbStoreObserver> &observer) override;
64     int32_t Unsubscribe(const std::string &event,
65         const std::shared_ptr<DistributedRdb::RdbStoreObserver> &observer) override;
66     int32_t Backup(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey,
67         bool isAsync, SlaveStatus &slaveStatus) override;
68     int32_t Restore(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey,
69         SlaveStatus &slaveStatus) override;
70     ExchangeStrategy GenerateExchangeStrategy(const SlaveStatus &status) override;
71 
72 protected:
73     std::pair<int32_t, ValueObject> ExecuteForValue(const std::string &sql,
74         const std::vector<ValueObject> &bindArgs = std::vector<ValueObject>());
75     int ExecuteSql(const std::string &sql, const std::vector<ValueObject> &bindArgs = std::vector<ValueObject>());
76 
77 private:
78     struct Suffix {
79         const char *suffix_ = nullptr;
80         const char *debug_ = nullptr;
81     };
82 
83     int InnerOpen(const RdbStoreConfig &config);
84     int Configure(const RdbStoreConfig &config, std::string &dbPath);
85     int SetPageSize(const RdbStoreConfig &config);
86     std::string GetSecManagerName(const RdbStoreConfig &config);
87     int SetEncrypt(const RdbStoreConfig &config);
88     int SetEncryptKey(const std::vector<uint8_t> &key, const RdbStoreConfig &config);
89     int SetServiceKey(const RdbStoreConfig &config, int32_t errCode);
90     int SetEncryptAgo(const RdbStoreConfig &config);
91     int SetJournalMode(const RdbStoreConfig &config);
92     int SetJournalSizeLimit(const RdbStoreConfig &config);
93     int SetAutoCheckpoint(const RdbStoreConfig &config);
94     int SetWalFile(const RdbStoreConfig &config);
95     int SetWalSyncMode(const std::string &syncMode);
96     void LimitPermission(const std::string &dbPath) const;
97 
98     int SetPersistWal();
99     int SetBusyTimeout(int timeout);
100 
101     int RegDefaultFunctions(sqlite3 *dbHandle);
102     static void MergeAssets(sqlite3_context *ctx, int argc, sqlite3_value **argv);
103     static void MergeAsset(sqlite3_context *ctx, int argc, sqlite3_value **argv);
104     static void CompAssets(std::map<std::string, ValueObject::Asset> &oldAssets,
105         std::map<std::string, ValueObject::Asset> &newAssets);
106     static void MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Asset &newAsset);
107 
108     int SetCustomFunctions(const RdbStoreConfig &config);
109     int SetCustomScalarFunction(const std::string &functionName, int argc, ScalarFunction *function);
110     int32_t UnsubscribeLocalDetail(const std::string &event,
111         const std::shared_ptr<DistributedRdb::RdbStoreObserver> &observer);
112     int32_t UnsubscribeLocalDetailAll(const std::string &event);
113     int32_t OpenDatabase(const std::string &dbPath, int openFileFlags);
114     int LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHandle);
115     RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig);
116     int CreateSlaveConnection(const RdbStoreConfig &config, bool checkSlaveExist = true);
117     int ExchangeSlaverToMaster(bool isRestore, SlaveStatus &status);
118     int IsRepairable();
119     int ExchangeVerify(bool isRestore);
120     static std::pair<int32_t, std::shared_ptr<SqliteConnection>> InnerCreate(const RdbStoreConfig &config,
121         bool isWrite);
122     static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = {
123         {"", "DB"},
124         {"-shm", "SHM"},
125         {"-wal", "WAL"},
126         {"-journal", "JOURNAL"},
127         {"-slaveFailure", nullptr},
128         {"-syncInterrupt", nullptr},
129         {".corruptedflg", nullptr}
130     };
131     static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets";
132     static constexpr const char *MERGE_ASSET_FUNC = "merge_asset";
133     static constexpr int CHECKPOINT_TIME = 1000;
134     static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000;
135     static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m
136     static constexpr int BACKUP_PRE_WAIT_TIME = 10;
137     static constexpr ssize_t SLAVE_WAL_SIZE_LIMIT = 2147483647; // 2147483647 = 2g - 1
138     static constexpr uint32_t NO_ITER = 0;
139     static constexpr uint32_t WAL_INDEX = 2;
140     static const int32_t regCreator_;
141     static const int32_t regRepairer_;
142     static const int32_t regDeleter_;
143     static const int32_t regCollector_;
144 
145     std::atomic<uint64_t> backupId_;
146     sqlite3 *dbHandle_;
147     bool isWriter_;
148     bool isReadOnly_;
149     bool isConfigured_ = false;
150     bool hasClientObserver_ = false;
151     JournalMode mode_ = JournalMode::MODE_WAL;
152     int maxVariableNumber_;
153     std::mutex mutex_;
154     std::string filePath;
155     std::shared_ptr<SqliteConnection> slaveConnection_;
156     std::map<std::string, ScalarFunctionInfo> customScalarFunctions_;
157     std::map<std::string, std::list<std::shared_ptr<RdbStoreLocalDbObserver>>> observers_;
158     const RdbStoreConfig config_;
159     std::atomic<SlaveStatus> slaveStatus_ = SlaveStatus::UNDEFINED;
160 };
161 } // namespace NativeRdb
162 } // namespace OHOS
163 #endif