• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef RELATIONAL_STORE
16 #include "sqlite_single_ver_relational_continue_token.h"
17 #include "sqlite_utils.h"
18 
19 namespace DistributedDB {
SQLiteSingleVerRelationalContinueToken(const SyncTimeRange & timeRange,const QueryObject & queryObject)20 SQLiteSingleVerRelationalContinueToken::SQLiteSingleVerRelationalContinueToken(
21     const SyncTimeRange &timeRange, const QueryObject &queryObject)
22     : isGettingDeletedData_(false), queryObj_(queryObject), tableName_(queryObj_.GetTableName()), timeRange_(timeRange)
23 {
24 }
25 
CheckValid() const26 bool SQLiteSingleVerRelationalContinueToken::CheckValid() const
27 {
28     bool isValid = (magicBegin_ == MAGIC_BEGIN && magicEnd_ == MAGIC_END);
29     if (!isValid) {
30         LOGE("Invalid continue token.");
31     }
32     return isValid;
33 }
34 
GetStatement(sqlite3 * db,sqlite3_stmt * & queryStmt,sqlite3_stmt * & fullStmt,bool & isGettingDeletedData)35 int SQLiteSingleVerRelationalContinueToken::GetStatement(sqlite3 *db, sqlite3_stmt *&queryStmt, sqlite3_stmt *&fullStmt,
36     bool &isGettingDeletedData)
37 {
38     isGettingDeletedData = isGettingDeletedData_;
39     if (isGettingDeletedData) {
40         return GetDeletedDataStmt(db, queryStmt);
41     }
42 
43     int errCode = GetQuerySyncStatement(db, queryStmt);
44     if (errCode != E_OK) {
45         return errCode;
46     }
47 
48     // if lastQueryTime equals 0, that means never sync before, need not to send miss query data.
49     // if queryObj is empty, that means to send all data now, need not to send miss query data.
50     if (timeRange_.lastQueryTime != 0 && !queryObj_.Empty()) {
51         errCode = GetMissQueryStatement(db, fullStmt);
52     }
53     if (errCode != E_OK) {
54         SQLiteUtils::ResetStatement(queryStmt, true, errCode);
55     }
56     return errCode;
57 }
58 
SetNextBeginTime(const DataItem & theLastItem)59 void SQLiteSingleVerRelationalContinueToken::SetNextBeginTime(const DataItem &theLastItem)
60 {
61     Timestamp nextBeginTime = theLastItem.timestamp + 1;
62     if (nextBeginTime > INT64_MAX) {
63         nextBeginTime = INT64_MAX;
64     }
65     if (!isGettingDeletedData_) {
66         timeRange_.beginTime = nextBeginTime;
67         timeRange_.lastQueryTime = std::max(nextBeginTime, timeRange_.lastQueryTime);
68         return;
69     }
70     if ((theLastItem.flag & DataItem::DELETE_FLAG) != 0) {  // The last one could be non-deleted.
71         timeRange_.deleteBeginTime = nextBeginTime;
72     }
73 }
74 
FinishGetData()75 void SQLiteSingleVerRelationalContinueToken::FinishGetData()
76 {
77     if (isGettingDeletedData_) {
78         timeRange_.deleteEndTime = 0;
79         return;
80     }
81     isGettingDeletedData_ = true;
82     timeRange_.endTime = 0;
83     return;
84 }
85 
IsGetAllDataFinished() const86 bool SQLiteSingleVerRelationalContinueToken::IsGetAllDataFinished() const
87 {
88     return timeRange_.beginTime >= timeRange_.endTime && timeRange_.deleteBeginTime >= timeRange_.deleteEndTime;
89 }
90 
GetQuerySyncStatement(sqlite3 * db,sqlite3_stmt * & stmt)91 int SQLiteSingleVerRelationalContinueToken::GetQuerySyncStatement(sqlite3 *db, sqlite3_stmt *&stmt)
92 {
93     int errCode = E_OK;
94     SqliteQueryHelper helper = queryObj_.GetQueryHelper(errCode);
95     if (errCode != E_OK) {
96         return errCode;
97     }
98     if (fieldNames_.empty()) {
99         LOGE("field names cannot be empty.");
100         return -E_INTERNAL_ERROR;
101     }
102     return helper.GetRelationalQueryStatement(db, timeRange_.beginTime, timeRange_.endTime, fieldNames_, stmt);
103 }
104 
GetMissQueryStatement(sqlite3 * db,sqlite3_stmt * & stmt)105 int SQLiteSingleVerRelationalContinueToken::GetMissQueryStatement(sqlite3 *db, sqlite3_stmt *&stmt)
106 {
107     int errCode = E_OK;
108     SqliteQueryHelper helper = queryObj_.GetQueryHelper(errCode);
109     if (errCode != E_OK) {
110         return errCode;
111     }
112     return helper.GetRelationalMissQueryStatement(db, timeRange_.lastQueryTime + 1, INT64_MAX, fieldNames_, stmt);
113 }
114 
GetDeletedDataStmt(sqlite3 * db,sqlite3_stmt * & stmt) const115 int SQLiteSingleVerRelationalContinueToken::GetDeletedDataStmt(sqlite3 *db, sqlite3_stmt *&stmt) const
116 {
117     // get stmt
118     const std::string sql = GetDeletedDataSQL();
119     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
120     if (errCode != E_OK) {
121         return errCode;
122     }
123 
124     // bind stmt
125     errCode = SQLiteUtils::BindInt64ToStatement(stmt, 1, timeRange_.deleteBeginTime); // 1 means begin time
126     if (errCode != E_OK) {
127         goto ERROR;
128     }
129     errCode = SQLiteUtils::BindInt64ToStatement(stmt, 2, timeRange_.deleteEndTime); // 2 means end time
130     if (errCode != E_OK) {
131         goto ERROR;
132     }
133     return errCode;
134 
135 ERROR:
136     SQLiteUtils::ResetStatement(stmt, true, errCode);
137     return errCode;
138 }
139 
GetQuery() const140 const QueryObject &SQLiteSingleVerRelationalContinueToken::GetQuery() const
141 {
142     return queryObj_;
143 }
144 
GetDeletedDataSQL() const145 std::string SQLiteSingleVerRelationalContinueToken::GetDeletedDataSQL() const
146 {
147     std::string tableName = DBConstant::RELATIONAL_PREFIX + tableName_ + "_log";
148     return "SELECT * FROM " + tableName +
149         " WHERE timestamp >= ? AND timestamp < ? AND (flag&0x03 = 0x03) ORDER BY timestamp ASC;";
150 }
151 
SetFieldNames(const std::vector<std::string> & fieldNames)152 void SQLiteSingleVerRelationalContinueToken::SetFieldNames(const std::vector<std::string> &fieldNames)
153 {
154     fieldNames_ = fieldNames;
155 }
156 
UpdateNextSyncOffset(int addOffset)157 void SQLiteSingleVerRelationalContinueToken::UpdateNextSyncOffset(int addOffset)
158 {
159     if (!queryObj_.HasLimit() || queryObj_.HasOrderBy()) {
160         return;
161     }
162     int limit;
163     int offset;
164     queryObj_.GetLimitVal(limit, offset);
165     if (limit < addOffset) {
166         LOGW("Sync data is over limit.");
167         return;
168     }
169     queryObj_.SetLimit(limit - addOffset, offset + addOffset);
170 }
171 
SetCloudTableSchema(const TableSchema & schema)172 void SQLiteSingleVerRelationalContinueToken::SetCloudTableSchema(const TableSchema &schema)
173 {
174     tableSchema_ = schema;
175 }
176 
GetCloudStatement(sqlite3 * db,CloudSyncData & cloudDataResult,sqlite3_stmt * & queryStmt,bool & isFirstTime)177 int SQLiteSingleVerRelationalContinueToken::GetCloudStatement(sqlite3 *db, CloudSyncData &cloudDataResult,
178     sqlite3_stmt *&queryStmt, bool &isFirstTime)
179 {
180     if (queryStmt_ != nullptr) {
181         queryStmt = queryStmt_;
182         isFirstTime = false;
183         return E_OK;
184     }
185     int errCode;
186     SqliteQueryHelper helper = queryObj_.GetQueryHelper(errCode);
187     if (errCode != E_OK) {
188         return errCode;
189     }
190     std::string sql = helper.GetRelationalCloudQuerySql(tableSchema_.fields, cloudDataResult.isCloudForcePushStrategy,
191         cloudDataResult.isCompensatedTask, cloudDataResult.mode);
192     errCode = helper.GetCloudQueryStatement(true, db, sql, queryStmt_);
193     if (errCode == E_OK) {
194         queryStmt = queryStmt_;
195     }
196     isFirstTime = true;
197     return errCode;
198 }
199 
GetCloudTableSchema(TableSchema & tableSchema) const200 void SQLiteSingleVerRelationalContinueToken::GetCloudTableSchema(TableSchema &tableSchema) const
201 {
202     tableSchema = tableSchema_;
203 }
204 
ReleaseCloudStatement()205 int SQLiteSingleVerRelationalContinueToken::ReleaseCloudStatement()
206 {
207     if (queryStmt_ == nullptr) {
208         return E_OK;
209     }
210     int errCode = E_OK;
211     SQLiteUtils::ResetStatement(queryStmt_, true, errCode);
212     queryStmt_ = nullptr;
213     return errCode;
214 }
215 
IsUseLocalSchema() const216 bool SQLiteSingleVerRelationalContinueToken::IsUseLocalSchema() const
217 {
218     return queryObj_.IsUseLocalSchema();
219 }
220 
GetRemoteDev() const221 std::string SQLiteSingleVerRelationalContinueToken::GetRemoteDev() const
222 {
223     return queryObj_.GetRemoteDev();
224 }
225 }  // namespace DistributedDB
226 #endif