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 #define LOG_TAG "SharedBlockSerializerInfo"
16 #include "shared_block_serializer_info.h"
17 
18 #include "logger.h"
19 #include "value_object.h"
20 
21 namespace OHOS {
22 namespace NativeRdb {
23 using namespace OHOS::Rdb;
24 
SharedBlockSerializerInfo(AppDataFwk::SharedBlock * sharedBlock,sqlite3_stmt * stat,int numColumns,int startPos)25 SharedBlockSerializerInfo::SharedBlockSerializerInfo(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *stat,
26     int numColumns, int startPos)
27     : sharedBlock_(sharedBlock), statement_(stat), anumColumns(numColumns), atotalRows(0), astartPos(startPos),
28       raddedRows(0)
29 {
30 }
31 
~SharedBlockSerializerInfo()32 SharedBlockSerializerInfo::~SharedBlockSerializerInfo() {}
33 
AddRow(int addedRows)34 int SharedBlockSerializerInfo::AddRow(int addedRows)
35 {
36     // Allocate a new field directory for the row.
37     int status = sharedBlock_->AllocRow();
38     if (status == AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
39         raddedRows = addedRows + 1;
40         return SQLITE_OK;
41     }
42     return SQLITE_FULL;
43 }
44 
Reset(int startPos)45 int SharedBlockSerializerInfo::Reset(int startPos)
46 {
47     int status = sharedBlock_->Clear();
48     if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
49         LOG_ERROR("SharedBlockSerializerInfo::Reset() Failed in Clear(), error=%{public}d.", status);
50         return SQLITE_ERROR;
51     }
52     status = sharedBlock_->SetColumnNum(anumColumns);
53     if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
54         LOG_ERROR("SharedBlockSerializerInfo::Reset() Failed in SetColumnNum(), error=%{public}d.", status);
55         return SQLITE_ERROR;
56     }
57     astartPos = startPos;
58     raddedRows = 0;
59     return SQLITE_OK;
60 }
61 
Finish(int addedRows,int totalRows)62 int SharedBlockSerializerInfo::Finish(int addedRows, int totalRows)
63 {
64     raddedRows = addedRows;
65     atotalRows = totalRows;
66     return SQLITE_OK;
67 }
68 
PutLong(int row,int column,sqlite3_int64 value)69 int SharedBlockSerializerInfo::PutLong(int row, int column, sqlite3_int64 value)
70 {
71     int status = sharedBlock_->PutLong(row, column, value);
72     if (status == AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
73         return SQLITE_OK;
74     }
75     sharedBlock_->FreeLastRow();
76     return SQLITE_FULL;
77 }
78 
PutDouble(int row,int column,double value)79 int SharedBlockSerializerInfo::PutDouble(int row, int column, double value)
80 {
81     int status = sharedBlock_->PutDouble(row, column, value);
82     if (status == AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
83         return SQLITE_OK;
84     }
85     sharedBlock_->FreeLastRow();
86     return SQLITE_FULL;
87 }
88 
PutBlob(int row,int column,const void * blob,int len)89 int SharedBlockSerializerInfo::PutBlob(int row, int column, const void *blob, int len)
90 {
91     auto action = &AppDataFwk::SharedBlock::PutBlob;
92     auto *declType = sqlite3_column_decltype(statement_, column);
93     if (declType != nullptr) {
94         std::string type(declType);
95         std::transform(type.begin(), type.end(), type.begin(), [](auto ch) { return std::toupper(ch); });
96         action = (type == ValueObject::DeclType<ValueObject::Asset>())         ? &AppDataFwk::SharedBlock::PutAsset
97                  : (type == ValueObject::DeclType<ValueObject::Assets>())      ? &AppDataFwk::SharedBlock::PutAssets
98                  : (type == ValueObject::DeclType<ValueObject::FloatVector>()) ? &AppDataFwk::SharedBlock::PutFloats
99                  : (type == ValueObject::DeclType<ValueObject::BigInt>())      ? &AppDataFwk::SharedBlock::PutBigInt
100                                                                                : &AppDataFwk::SharedBlock::PutBlob;
101     }
102 
103     int status = (sharedBlock_->*action)(row, column, blob, len);
104     if (status == AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
105         return SQLITE_OK;
106     }
107     sharedBlock_->FreeLastRow();
108     return SQLITE_FULL;
109 }
110 
PutNull(int row,int column)111 int SharedBlockSerializerInfo::PutNull(int row, int column)
112 {
113     int status = sharedBlock_->PutNull(row, column);
114     if (status == AppDataFwk::SharedBlock::SHARED_BLOCK_OK) {
115         return SQLITE_OK;
116     }
117     sharedBlock_->FreeLastRow();
118     LOG_ERROR("Failed allocating space for a null in column %{public}d, error=%{public}d", column, status);
119     return SQLITE_FULL;
120 }
121 
PutOther(int row,int column)122 int SharedBlockSerializerInfo::PutOther(int row, int column)
123 {
124     sharedBlock_->FreeLastRow();
125     return SQLITE_ERROR;
126 }
127 } // namespace NativeRdb
128 } // namespace OHOS