• 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 
16 
17 #include "sqlite_shared_result_set.h"
18 #include <algorithm>
19 #include <memory>
20 #include <rdb_errno.h>
21 #include "logger.h"
22 
23 namespace OHOS {
24 namespace NativeRdb {
SqliteSharedResultSet(std::shared_ptr<RdbStoreImpl> rdbSreImpl,std::string path,std::string sql,const std::vector<std::string> & bindArgs)25 SqliteSharedResultSet::SqliteSharedResultSet(std::shared_ptr<RdbStoreImpl> rdbSreImpl, std::string path,
26     std::string sql, const std::vector<std::string> &bindArgs)
27     : AbsSharedResultSet(path), resultSetBlockCapacity(0), isOnlyFillResultSetBlock(false), rdbStoreImpl(rdbSreImpl),
28       qrySql(sql), selectionArgVec(bindArgs), rowNum(NO_COUNT)
29 {}
30 
~SqliteSharedResultSet()31 SqliteSharedResultSet::~SqliteSharedResultSet() {}
32 
GetAllColumnNames(std::vector<std::string> & columnNames)33 int SqliteSharedResultSet::GetAllColumnNames(std::vector<std::string> &columnNames)
34 {
35     int errCode = PrepareStep();
36     if (errCode) {
37         return errCode;
38     }
39     int columnCount = 0;
40     // Get the total number of columns
41     errCode = sqliteStatement->GetColumnCount(columnCount);
42     if (errCode) {
43         return errCode;
44     }
45     columnNames.clear();
46     for (int i = 0; i < columnCount; i++) {
47         std::string columnName;
48         errCode = sqliteStatement->GetColumnName(i, columnName);
49         if (errCode) {
50             columnNames.clear();
51             return errCode;
52         }
53         columnNames.push_back(columnName);
54     }
55 
56     rdbStoreImpl->EndStepQuery();
57     sqliteStatement = nullptr;
58 
59     return E_OK;
60 }
61 
GetRowCount(int & count)62 int SqliteSharedResultSet::GetRowCount(int &count)
63 {
64     if (rowNum == NO_COUNT) {
65         FillSharedBlock(0);
66     }
67     count = rowNum;
68     return E_OK;
69 }
70 
Close()71 int SqliteSharedResultSet::Close()
72 {
73     std::lock_guard<std::mutex> lock(sessionMutex);
74 
75     AbsSharedResultSet::Close();
76 
77     return E_OK;
78 }
79 
80 /**
81  * Get the rdb store that this result set is associated with.
82  */
GetRdbStore() const83 std::shared_ptr<RdbStore> SqliteSharedResultSet::GetRdbStore() const
84 {
85     return rdbStoreImpl;
86 }
87 
OnGo(int oldPosition,int newPosition)88 bool SqliteSharedResultSet::OnGo(int oldPosition, int newPosition)
89 {
90     if (GetBlock() == nullptr) {
91         FillSharedBlock(newPosition);
92         return true;
93     }
94     if (newPosition >= (int)GetBlock()->GetRowNum()) {
95         FillSharedBlock(newPosition);
96     }
97     return true;
98 }
99 
100 /**
101  * Calculate a proper start position to fill the block.
102  */
PickFillBlockStartPosition(int resultSetPosition,int blockCapacity) const103 int SqliteSharedResultSet::PickFillBlockStartPosition(int resultSetPosition, int blockCapacity) const
104 {
105     return std::max(resultSetPosition - blockCapacity / PICK_POS, 0);
106 }
107 
FillSharedBlock(int requiredPos)108 void SqliteSharedResultSet::FillSharedBlock(int requiredPos)
109 {
110     ClearBlock();
111 
112     if (!HasBlock()) {
113         LOG_ERROR("SqliteSharedResultSet::FillSharedBlock sharedBlock is null.");
114         return;
115     }
116 
117     std::vector<ValueObject> bindArgs;
118     size_t size = selectionArgVec.size();
119 
120     for (size_t i = 0; i < size; i++) {
121         ValueObject vauObj(selectionArgVec[i]);
122         bindArgs.push_back(vauObj);
123     }
124 
125     if (rowNum == NO_COUNT) {
126         rdbStoreImpl->ExecuteForSharedBlock(rowNum, GetBlock(), requiredPos, requiredPos, true, qrySql, bindArgs);
127         resultSetBlockCapacity = static_cast<int>(GetBlock()->GetRowNum());
128     } else {
129         int startPos =
130             isOnlyFillResultSetBlock ? requiredPos : PickFillBlockStartPosition(requiredPos, resultSetBlockCapacity);
131         rdbStoreImpl->ExecuteForSharedBlock(rowNum, GetBlock(), startPos, requiredPos, false, qrySql, bindArgs);
132     }
133 }
134 
SetBlock(AppDataFwk::SharedBlock * block)135 void SqliteSharedResultSet::SetBlock(AppDataFwk::SharedBlock *block)
136 {
137     AbsSharedResultSet::SetBlock(block);
138     rowNum = NO_COUNT;
139 }
140 
141 /**
142  * If isOnlyFillResultSetBlockInput is true, use the input requiredPos to fill the block, otherwise pick the value
143  * from requirePos and resultSetBlockCapacity.
144  */
SetFillBlockForwardOnly(bool isOnlyFillResultSetBlockInput)145 void SqliteSharedResultSet::SetFillBlockForwardOnly(bool isOnlyFillResultSetBlockInput)
146 {
147     isOnlyFillResultSetBlock = isOnlyFillResultSetBlockInput;
148 }
149 
Finalize()150 void SqliteSharedResultSet::Finalize()
151 {
152     if (!AbsSharedResultSet::IsClosed()) {
153         if (rdbStoreImpl->IsOpen()) {
154             std::string filePath = rdbStoreImpl->GetPath();
155             std::string name = rdbStoreImpl->IsMemoryRdb() ? ":memory" : filePath;
156         }
157         Close();
158     }
159 }
160 
PrepareStep()161 int SqliteSharedResultSet::PrepareStep()
162 {
163     if (IsClosed()) {
164         return E_STEP_RESULT_CLOSED;
165     }
166     if (sqliteStatement != nullptr) {
167         return CheckSession();
168     }
169     int errCode;
170     sqliteStatement = rdbStoreImpl->BeginStepQuery(errCode, qrySql, selectionArgVec);
171     if (sqliteStatement == nullptr) {
172         rdbStoreImpl->EndStepQuery();
173         return errCode;
174     }
175     tid = std::this_thread::get_id();
176     return E_OK;
177 }
178 
CheckSession()179 int SqliteSharedResultSet::CheckSession()
180 {
181     if (std::this_thread::get_id() != tid) {
182         return E_STEP_RESULT_SET_CROSS_THREADS;
183     }
184     return E_OK;
185 }
186 } // namespace NativeRdb
187 } // namespace OHOS