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     int SetEncrypt(const RdbStoreConfig &config);
87     int SetEncryptKey(const std::vector<uint8_t> &key, const RdbStoreConfig &config);
88     int SetServiceKey(const RdbStoreConfig &config, int32_t errCode);
89     int SetEncryptAgo(const RdbStoreConfig &config);
90     int SetJournalMode(const RdbStoreConfig &config);
91     int SetJournalSizeLimit(const RdbStoreConfig &config);
92     int SetAutoCheckpoint(const RdbStoreConfig &config);
93     int SetWalFile(const RdbStoreConfig &config);
94     int SetWalSyncMode(const std::string &syncMode);
95     void LimitPermission(const std::string &dbPath) const;
96 
97     int SetPersistWal();
98     int SetBusyTimeout(int timeout);
99 
100     int RegDefaultFunctions(sqlite3 *dbHandle);
101     static void MergeAssets(sqlite3_context *ctx, int argc, sqlite3_value **argv);
102     static void MergeAsset(sqlite3_context *ctx, int argc, sqlite3_value **argv);
103     static void CompAssets(std::map<std::string, ValueObject::Asset> &oldAssets,
104         std::map<std::string, ValueObject::Asset> &newAssets);
105     static void MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Asset &newAsset);
106 
107     int SetCustomFunctions(const RdbStoreConfig &config);
108     int SetCustomScalarFunction(const std::string &functionName, int argc, ScalarFunction *function);
109     int32_t UnsubscribeLocalDetail(const std::string &event,
110         const std::shared_ptr<DistributedRdb::RdbStoreObserver> &observer);
111     int32_t UnsubscribeLocalDetailAll(const std::string &event);
112     int32_t OpenDatabase(const std::string &dbPath, int openFileFlags);
113     int LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHandle);
114     RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig);
115     int CreateSlaveConnection(const RdbStoreConfig &config, bool checkSlaveExist = true);
116     int ExchangeSlaverToMaster(bool isRestore, SlaveStatus &status);
117     int IsRepairable();
118     int ExchangeVerify(bool isRestore);
119     static std::pair<int32_t, std::shared_ptr<SqliteConnection>> InnerCreate(const RdbStoreConfig &config,
120         bool isWrite);
121     static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = {
122         {"", "DB"},
123         {"-shm", "SHM"},
124         {"-wal", "WAL"},
125         {"-journal", "JOURNAL"},
126         {"-slaveFailure", nullptr},
127         {"-syncInterrupt", nullptr},
128         {".corruptedflg", nullptr}
129     };
130     static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets";
131     static constexpr const char *MERGE_ASSET_FUNC = "merge_asset";
132     static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000;
133     static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m
134     static constexpr int BACKUP_PRE_WAIT_TIME = 10;
135     static constexpr ssize_t SLAVE_WAL_SIZE_LIMIT = 2147483647; // 2147483647 = 2g - 1
136     static constexpr uint32_t NO_ITER = 0;
137     static constexpr uint32_t WAL_INDEX = 2;
138     static const int32_t regCreator_;
139     static const int32_t regRepairer_;
140     static const int32_t regDeleter_;
141     static const int32_t regCollector_;
142 
143     std::atomic<uint64_t> backupId_;
144     sqlite3 *dbHandle_;
145     bool isWriter_;
146     bool isReadOnly_;
147     bool isConfigured_ = false;
148     bool hasClientObserver_ = false;
149     JournalMode mode_ = JournalMode::MODE_WAL;
150     int maxVariableNumber_;
151     std::mutex mutex_;
152     std::string filePath;
153     std::shared_ptr<SqliteConnection> slaveConnection_;
154     std::map<std::string, ScalarFunctionInfo> customScalarFunctions_;
155     std::map<std::string, std::list<std::shared_ptr<RdbStoreLocalDbObserver>>> observers_;
156     const RdbStoreConfig config_;
157 };
158 } // namespace NativeRdb
159 } // namespace OHOS
160 #endif