• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "concurrent_map.h"
27 #include "connection.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 Delete(const std::string &path);
46     static int32_t Repair(const RdbStoreConfig &config);
47     static std::map<std::string, Info> Collect(const RdbStoreConfig &config);
48     static int32_t CheckReplicaIntegrity(const RdbStoreConfig &config);
49     static int32_t ClientCleanUp();
50     static int32_t OpenSSLCleanUp();
51     SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection, bool isSlave = false);
52     ~SqliteConnection();
53     int32_t VerifyAndRegisterHook(const RdbStoreConfig &config) override;
54     int TryCheckPoint(bool timeout) override;
55     int LimitWalSize() override;
56     int ConfigLocale(const std::string &localeStr) override;
57     int CleanDirtyData(const std::string &table, uint64_t cursor) override;
58     int ResetKey(const RdbStoreConfig &config) override;
59     int32_t Rekey(const RdbStoreConfig::CryptoParam &cryptoParam) override;
60     int32_t GetJournalMode() override;
61     std::pair<int32_t, Stmt> CreateStatement(const std::string &sql, SConn conn) override;
62     std::pair<int32_t, Stmt> CreateReplicaStatement(const std::string &sql, SConn conn) override;
63     int CheckReplicaForRestore() override;
64     bool IsWriter() const override;
65     int SubscribeTableChanges(const Notifier &notifier) override;
66     int GetMaxVariable() const override;
67     int32_t GetDBType() const override;
68     int32_t ClearCache(bool isForceClear = false) override;
69     int32_t Subscribe(const std::shared_ptr<DistributedDB::StoreObserver> &observer) override;
70     int32_t Unsubscribe(const std::shared_ptr<DistributedDB::StoreObserver> &observer) override;
71     int32_t Backup(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey, bool isAsync,
72         std::shared_ptr<SlaveStatus> slaveStatus, bool verifyDb = true) override;
73     int32_t Restore(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey,
74         std::shared_ptr<SlaveStatus> slaveStatus) override;
75     ExchangeStrategy GenerateExchangeStrategy(std::shared_ptr<SlaveStatus> status, bool isRelpay) override;
76     int SetKnowledgeSchema(const DistributedRdb::RdbKnowledgeSchema &schema) override;
77     int CleanDirtyLog(const std::string &table, uint64_t cursor) override;
78     static bool IsSupportBinlog(const RdbStoreConfig &config);
79 protected:
80     std::pair<int32_t, ValueObject> ExecuteForValue(
81         const std::string &sql, const std::vector<ValueObject> &bindArgs = std::vector<ValueObject>());
82     int ExecuteSql(const std::string &sql, const std::vector<ValueObject> &bindArgs = std::vector<ValueObject>());
83     int RegisterAlgo(const std::string &clstAlgoName, ClusterAlgoFunc func) override;
84 
85 private:
86     struct Suffix {
87         const char *suffix_ = nullptr;
88         const char *debug_ = nullptr;
89     };
90 
91     enum SlaveOpenPolicy : int32_t {
92         FORCE_OPEN = 0,
93         OPEN_IF_DB_VALID // DB exists and there are no -slaveFailure and -syncInterrupt files
94     };
95 
96     int InnerOpen(const RdbStoreConfig &config);
97     int Configure(const RdbStoreConfig &config, std::string &dbPath);
98     int SetPageSize(const RdbStoreConfig &config);
99     int SetEncrypt(const RdbStoreConfig &config);
100     int SetEncryptKey(const std::vector<uint8_t> &key, const RdbStoreConfig &config);
101     int SetServiceKey(const RdbStoreConfig &config, int32_t errCode);
102     int SetEncryptAgo(const RdbStoreConfig &config);
103     int SetJournalMode(const RdbStoreConfig &config);
104     int SetEncryptAgo(const RdbStoreConfig::CryptoParam &cryptoParam);
105     int SetAutoCheckpoint(const RdbStoreConfig &config);
106     int SetWalFile(const RdbStoreConfig &config);
107     int SetWalSyncMode(const std::string &syncMode);
108     int SetTokenizer(const RdbStoreConfig &config);
109     int SetBinlog();
110     void LimitPermission(const RdbStoreConfig &config, const std::string &dbPath) const;
111 
112     int SetPersistWal(const RdbStoreConfig &config);
113     int SetBusyTimeout(int timeout);
114     void SetDwrEnable(const RdbStoreConfig &config);
115     void SetIsSupportBinlog(bool isSupport);
116 
117     int RegDefaultFunctions(sqlite3 *dbHandle);
118     int SetCustomFunctions(const RdbStoreConfig &config);
119     int SetCustomScalarFunction(const std::string &functionName, int argc, ScalarFunction *function);
120     int32_t UnsubscribeLocalDetail(
121         const std::string &event, const std::shared_ptr<DistributedRdb::RdbStoreObserver> &observer);
122     int32_t UnsubscribeLocalDetailAll(const std::string &event);
123     int32_t OpenDatabase(const std::string &dbPath, int openFileFlags);
124     int LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHandle);
125     RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig);
126     std::pair<int32_t, std::shared_ptr<SqliteConnection>> CreateSlaveConnection(
127         const RdbStoreConfig &config, SlaveOpenPolicy slaveOpenPolicy);
128     int ExchangeSlaverToMaster(bool isRestore, bool verifyDb, std::shared_ptr<SlaveStatus> curStatus);
129     int ExchangeVerify(bool isRestore);
130     int SqliteBackupStep(bool isRestore, sqlite3_backup *pBackup, std::shared_ptr<SlaveStatus> curStatus);
131     int SqliteNativeBackup(bool isRestore, std::shared_ptr<SlaveStatus> curStatus);
132     int VerifySlaveIntegrity();
133     bool IsDbVersionBelowSlave();
134     int RegisterStoreObs();
135     int RegisterClientObs();
136     int RegisterHookIfNecessary();
137     std::pair<int32_t, Stmt> CreateStatementInner(const std::string &sql, SConn conn,
138         sqlite3 *db, bool isFromReplica);
139     void ReplayBinlog(const RdbStoreConfig &config);
140     ExchangeStrategy CompareWithSlave(int64_t mCount, int64_t mIdxCount);
141     static std::pair<int32_t, std::shared_ptr<SqliteConnection>> InnerCreate(
142         const RdbStoreConfig &config, bool isWrite, bool isReusableReplica = false);
143     static void BinlogOnErrFunc(void *pCtx, int errNo, char *errMsg, const char *dbPath);
144     static void BinlogCloseHandle(sqlite3 *dbHandle);
145     static int CheckPathExist(const std::string &dbPath);
146     static int BinlogOpenHandle(const std::string &dbPath, sqlite3 *&dbHandle, bool isMemoryRdb);
147     static void BinlogSetConfig(sqlite3 *dbHandle);
148     static void BinlogOnFullFunc(void *pCtx, unsigned short currentCount, const char *dbPath);
149     static void ReplayBinlog(const std::string &dbPath,
150         std::shared_ptr<SqliteConnection> slaveConn, bool isNeedClean);
151     static std::string GetBinlogFolderPath(const std::string &dbPath);
152     static constexpr const char *BINLOG_FOLDER_SUFFIX = "_binlog";
153     static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = { { "", "DB" }, { "-shm", "SHM" }, { "-wal", "WAL" },
154         { "-dwr", "DWR" }, { "-journal", "JOURNAL" }, { "-slaveFailure", nullptr }, { "-syncInterrupt", nullptr },
155         { ".corruptedflg", nullptr }, { "-compare", nullptr }, { "-walcompress", nullptr },
156         { "-journalcompress", nullptr }, { "-shmcompress", nullptr } };
157     static constexpr int CHECKPOINT_TIME = 500;
158     static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000;
159     static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m
160     static constexpr int BACKUP_PRE_WAIT_TIME = 10;
161     static constexpr int RESTORE_PRE_WAIT_TIME = 100;
162     static constexpr ssize_t SLAVE_WAL_SIZE_LIMIT = 2147483647;       // 2147483647 = 2g - 1
163     static constexpr ssize_t SLAVE_INTEGRITY_CHECK_LIMIT = 524288000; // 524288000 == 1024 * 1024 * 500
164     static constexpr unsigned short BINLOG_FILE_NUMS_LIMIT = 2;
165     static constexpr uint32_t BINLOG_FILE_SIZE_LIMIT = 1024 * 1024 * 4; // 4194304 == 1024 * 1024 * 4
166     static constexpr uint32_t NO_ITER = 0;
167     static constexpr uint32_t DB_INDEX = 0;
168     static constexpr uint32_t WAL_INDEX = 2;
169     static const int32_t regCreator_;
170     static const int32_t regRepairer_;
171     static const int32_t regDeleter_;
172     static const int32_t regCollector_;
173     static const int32_t regReplicaChecker_;
174     static const int32_t regDbClientCleaner_;
175     static const int32_t regOpenSSLCleaner_;
176     static ConcurrentMap<std::string, std::weak_ptr<SqliteConnection>> reusableReplicas_;
177     using EventHandle = int (SqliteConnection::*)();
178     struct HandleInfo {
179         RegisterType Type;
180         EventHandle handle;
181     };
182     static constexpr HandleInfo onEventHandlers_[RegisterType::OBSERVER_END] = {
183         { RegisterType::STORE_OBSERVER, &SqliteConnection::RegisterStoreObs },
184         { RegisterType::CLIENT_OBSERVER, &SqliteConnection::RegisterClientObs },
185     };
186 
187     std::atomic<uint64_t> backupId_;
188     sqlite3 *dbHandle_;
189     bool isWriter_;
190     bool isReadOnly_;
191     bool isConfigured_ = false;
192     bool isSupportBinlog_ = false;
193     bool isSlave_ = false;
194     bool isReplay_ = false;
195     JournalMode mode_ = JournalMode::MODE_WAL;
196     int maxVariableNumber_;
197     std::shared_ptr<SqliteConnection> slaveConnection_;
198     std::map<std::string, ScalarFunctionInfo> customScalarFunctions_;
199     const RdbStoreConfig config_;
200 };
201 } // namespace NativeRdb
202 } // namespace OHOS
203 #endif