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 ¬ifier) 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