1 /*
2  * Copyright (c) 2021 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 SQLITE_MULTI_VER_TRANSACTION_H
17 #define SQLITE_MULTI_VER_TRANSACTION_H
18 
19 #ifndef OMIT_MULTI_VER
20 #include <string>
21 #include <vector>
22 #include <mutex>
23 
24 #include "sqlite_import.h"
25 #include "db_types.h"
26 #include "kvdb_properties.h"
27 #include "ikvdb_multi_ver_transaction.h"
28 #include "macro_utils.h"
29 #include "multi_ver_value_object.h"
30 #include "generic_multi_ver_kv_entry.h"
31 
32 namespace DistributedDB {
33 class SQLiteMultiVerTransaction : public IKvDBMultiVerTransaction {
34 public:
35     SQLiteMultiVerTransaction();
36     ~SQLiteMultiVerTransaction() override;
37 
38     // Delete the copy and assign constructors
39     DISABLE_COPY_ASSIGN_MOVE(SQLiteMultiVerTransaction);
40 
41     int Initialize(const std::string &uri, bool isReadOnly, CipherType type, const CipherPassword &passwd);
42 
43     int Put(const Key &key, const Value &value) override;
44 
45     int Delete(const Key &key) override;
46 
47     int Clear() override;
48 
49     int Get(const Key &key, Value &value) const override;
50 
51     int GetEntries(const Key &keyPrefix, std::vector<Entry> &entries) const override;
52 
53     int PutBatch(const std::vector<Entry> &entries);
54 
55     int PutBatch(const std::vector<MultiVerKvEntry *> &entries, bool isLocal, std::vector<Value> &values) override;
56 
57     int GetDiffEntries(const Version &begin, const Version &end, MultiVerDiffData &data) const override;
58 
59     int GetMaxVersion(MultiVerDataType type, Version &maxVersion) const override;
60 
61     int ClearEntriesByVersion(const Version &versionInfo) override;
62 
63     int StartTransaction() override;
64 
65     int RollBackTransaction() override;
66 
67     int CommitTransaction() override;
68 
69     int GetEntriesByVersion(Version version, std::list<MultiVerTrimedVersionData> &data) const override;
70 
71     // Get Entries from the version.
72     int GetEntriesByVersion(const Version &versionInfo, std::vector<MultiVerKvEntry *> &entries) const override;
73 
74     // Update the timestamp of the version.
75     int UpdateTimestampByVersion(const Version &version, Timestamp stamp) const override;
76 
77     bool IsDataChanged() const override;
78 
79     // Get the max timestamp to generate the new version for the writing transaction
80     Timestamp GetCurrentMaxTimestamp() const override;
81 
82     // Reset the version.
83     void ResetVersion();
84 
85     // Reset the transaction while committing failed.
86     int Reset(CipherType type, const CipherPassword &passwd);
87 
88     // Check if the entry already cleared
89     bool IsRecordCleared(const Timestamp timestamp) const override;
90 
91     void SetVersion(const Version &versionInfo) override;
92 
93     Version GetVersion() const override;
94 
95     int GetOverwrittenClearTypeEntries(Version clearVersion, std::list<MultiVerTrimedVersionData> &data) const override;
96 
97     int GetOverwrittenNonClearTypeEntries(Version version, const Key &hashKey,
98         std::list<MultiVerTrimedVersionData> &data) const override;
99 
100     int DeleteEntriesByHashKey(Version version, const Key &hashKey) override;
101 
102     int GetValueForTrimSlice(const Key &hashKey, const Version version, Value &value) const override;
103 
104     int CheckIfNeedSaveRecord(sqlite3_stmt *statement, const MultiVerKvEntry *multiVerKvEntry,
105         bool &isNeedSave, Value &origVal) const;
106 
107 private:
108     struct GetEntriesStatements {
109         sqlite3_stmt *getEntriesStatement = nullptr;
110         sqlite3_stmt *hashFilterStatement = nullptr;
111     };
112 
113     enum EntryOperator {
114         INSERT,
115         UPDATE,
116         DELETE,
117         CLEAR,
118         FAIL,
119     };
120 
121     static int GetRawMultiVerEntry(sqlite3_stmt *statement, MultiVerEntryData &keyEntry);
122 
123     static int GetRawDataByVersion(sqlite3_stmt *&statement, const Version &version,
124         std::vector<MultiVerEntryData> &entries);
125 
126     static int GetDiffOperator(int errCode, uint64_t flag);
127 
128     static int BindAddRecordKeysToStatement(sqlite3_stmt *statement, const Key &key,
129         const MultiVerEntryAuxData &data);
130 
131     int AddRecord(const Key &key, const Value &value, const MultiVerEntryAuxData &data);
132 
133     void ClassifyDiffEntries(int errCode, uint64_t flag, const Value &value,
134         MultiVerEntryData &item, MultiVerDiffData &data) const;
135 
136     void GetClearId() const;
137 
138     int BindClearIdAndVersion(sqlite3_stmt *statement, int index) const;
139 
140     int BindQueryEntryArgs(sqlite3_stmt *statement, const Key &key) const;
141 
142     int BindQueryEntriesArgs(sqlite3_stmt *statement, const Key &key) const;
143 
144     int BindAddRecordArgs(sqlite3_stmt *statement, const Key &key, const Value &value,
145         const MultiVerEntryAuxData &data) const;
146 
147     int GetOneEntry(const GetEntriesStatements &statements, const Key &lastKey, Entry &entry, int &errCode) const;
148 
149     int RemovePrePutEntries(const Version &versionInfo, Timestamp timestamp);
150 
151     int CheckToSaveRecord(const MultiVerKvEntry *entry, bool &isNeedSave, std::vector<Value> &values);
152 
153     // Check if the entry with later timestamp already exist in the database
154     int CheckIfNeedSaveRecord(const MultiVerKvEntry *multiVerKvEntry, bool &isNeedSave, Value &value) const;
155 
156     int PrepareForGetEntries(const Key &keyPrefix, GetEntriesStatements &statements) const;
157 
158     int ReleaseGetEntriesStatements(GetEntriesStatements &statements) const;
159 
160     int GetKeyAndValueByHashKey(sqlite3_stmt *statement, const Key &hashKey, Key &key, Value &value,
161         bool isNeedReadKey) const;
162 
163     int GetOriginKeyValueByHash(MultiVerEntryData &item, Value &value) const;
164 
165     int GetPrePutValues(const Version &versionInfo, Timestamp timestamp, std::vector<Value> &values) const;
166 
167     static const std::string CREATE_TABLE_SQL;
168     static const std::string CREATE_TABLE_VERSION_INDEX_SQL;
169     static const std::string CREATE_TABLE_FLAG_INDEX_SQL;
170     static const std::string SELECT_ONE_SQL; // select the rowid
171     static const std::string SELECT_BATCH_SQL; // select the rowid and the key
172     static const std::string SELECT_HASH_ENTRY_SQL; // select the data according the hash key
173     static const std::string SELECT_ONE_VER_SQL; // select the rowid
174     static const std::string SELECT_BATCH_VER_SQL; // select the rowid and the key
175     static const std::string SELECT_ONE_VER_RAW_SQL;
176     static const std::string INSERT_SQL; // insert or replace the values
177     static const std::string DELETE_SQL; // delete the key-value record
178     static const std::string SELECT_ONE_BY_KEY_TIMESTAMP_SQL; // get one by key and timestamp
179 
180     static const std::string DELETE_VER_SQL;
181     static const std::string SELECT_PRE_PUT_VER_DATA_SQL;
182     static const std::string DELETE_PRE_PUT_VER_DATA_SQL;
183     static const std::string SELECT_LATEST_CLEAR_ID;
184     static const std::string SELECT_MAX_LOCAL_VERSION;
185     static const std::string SELECT_MAX_VERSION;
186     static const std::string SELECT_MAX_TIMESTAMP;
187     static const std::string UPDATE_VERSION_TIMESTAMP;
188     static const std::string SELECT_OVERWRITTEN_CLEAR_TYPE;
189     static const std::string SELECT_OVERWRITTEN_NO_CLEAR_TYPE;
190     static const std::string DELETE_BY_VER_HASHKEY_SQL;
191     static const std::string SELECT_BY_HASHKEY_VER_SQL;
192 
193     static const uint64_t ADD_FLAG = 0x01; // add or replace the record.
194     static const uint64_t DEL_FLAG = 0x02; // delete the record.
195     static const uint64_t CLEAR_FLAG = 0x03; // clear all the record.
196 
197     static const uint64_t LOCAL_FLAG = 0x08; // local flag for read.
198     static const uint64_t OPERATE_MASK = 0x07; // operate mask for add, delete
199 
200     std::mutex resetMutex_;
201     mutable std::mutex readMutex_;
202 
203     mutable int64_t clearId_; // for query the result after the clear operation in the same commit.
204     mutable int64_t clearTime_; // for query the result after the clear operation
205     mutable uint64_t currentMaxTimestamp_;
206     Version version_; // the read version or the current commit version.
207     sqlite3 *db_;
208     std::string uri_;
209     bool isReadOnly_;
210     bool isDataChanged_; // whether the transaction has new record.
211 };
212 } // namespace DistributedDB
213 
214 #endif // SQLITE_MULTI_VER_TRANSACTION_H
215 #endif