• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "sqlite_relational_utils.h"
17 #include "db_errno.h"
18 #include "cloud/cloud_db_types.h"
19 #include "sqlite_utils.h"
20 
21 namespace DistributedDB {
GetDataValueByType(sqlite3_stmt * statement,int cid,DataValue & value)22 int SQLiteRelationalUtils::GetDataValueByType(sqlite3_stmt *statement, int cid, DataValue &value)
23 {
24     if (statement == nullptr || cid < 0 || cid >= sqlite3_column_count(statement)) {
25         return -E_INVALID_ARGS;
26     }
27 
28     int errCode = E_OK;
29     int storageType = sqlite3_column_type(statement, cid);
30     switch (storageType) {
31         case SQLITE_INTEGER: {
32             value = static_cast<int64_t>(sqlite3_column_int64(statement, cid));
33             break;
34         }
35         case SQLITE_FLOAT: {
36             value = sqlite3_column_double(statement, cid);
37             break;
38         }
39         case SQLITE_BLOB: {
40             std::vector<uint8_t> blobValue;
41             errCode = SQLiteUtils::GetColumnBlobValue(statement, cid, blobValue);
42             if (errCode != E_OK) {
43                 return errCode;
44             }
45             auto blob = new (std::nothrow) Blob;
46             if (blob == nullptr) {
47                 return -E_OUT_OF_MEMORY;
48             }
49             blob->WriteBlob(blobValue.data(), static_cast<uint32_t>(blobValue.size()));
50             errCode = value.Set(blob);
51             break;
52         }
53         case SQLITE_NULL: {
54             break;
55         }
56         case SQLITE3_TEXT: {
57             std::string str;
58             (void)SQLiteUtils::GetColumnTextValue(statement, cid, str);
59             value = str;
60             if (value.GetType() != StorageType::STORAGE_TYPE_TEXT) {
61                 errCode = -E_OUT_OF_MEMORY;
62             }
63             break;
64         }
65         default: {
66             break;
67         }
68     }
69     return errCode;
70 }
71 
GetSelectValues(sqlite3_stmt * stmt)72 std::vector<DataValue> SQLiteRelationalUtils::GetSelectValues(sqlite3_stmt *stmt)
73 {
74     std::vector<DataValue> values;
75     for (int cid = 0, colCount = sqlite3_column_count(stmt); cid < colCount; ++cid) {
76         DataValue value;
77         (void)GetDataValueByType(stmt,  cid, value);
78         values.emplace_back(std::move(value));
79     }
80     return values;
81 }
82 
GetCloudValueByType(sqlite3_stmt * statement,int type,int cid,Type & cloudValue)83 int SQLiteRelationalUtils::GetCloudValueByType(sqlite3_stmt *statement, int type, int cid, Type &cloudValue)
84 {
85     if (statement == nullptr || cid < 0 || cid >= sqlite3_column_count(statement)) {
86         return -E_INVALID_ARGS;
87     }
88     switch (sqlite3_column_type(statement, cid)) {
89         case SQLITE_INTEGER: {
90             if (type == TYPE_INDEX<bool>) {
91                 cloudValue = static_cast<bool>(sqlite3_column_int(statement, cid));
92                 break;
93             }
94             cloudValue = static_cast<int64_t>(sqlite3_column_int64(statement, cid));
95             break;
96         }
97         case SQLITE_FLOAT: {
98             cloudValue = sqlite3_column_double(statement, cid);
99             break;
100         }
101         case SQLITE_BLOB: {
102             std::vector<uint8_t> blobValue;
103             int errCode = SQLiteUtils::GetColumnBlobValue(statement, cid, blobValue);
104             if (errCode != E_OK) {
105                 return errCode;
106             }
107             cloudValue = blobValue;
108             break;
109         }
110         case SQLITE3_TEXT: {
111             bool isBlob = (type == TYPE_INDEX<Bytes> || type == TYPE_INDEX<Asset> || type == TYPE_INDEX<Assets>);
112             if (isBlob) {
113                 std::vector<uint8_t> blobValue;
114                 int errCode = SQLiteUtils::GetColumnBlobValue(statement, cid, blobValue);
115                 if (errCode != E_OK) {
116                     return errCode;
117                 }
118                 cloudValue = blobValue;
119                 break;
120             }
121             std::string str;
122             (void)SQLiteUtils::GetColumnTextValue(statement, cid, str);
123             cloudValue = str;
124             break;
125         }
126         default: {
127             cloudValue = Nil();
128         }
129     }
130     return E_OK;
131 }
132 
CalCloudValueLen(Type & cloudValue,uint32_t & totalSize)133 void SQLiteRelationalUtils::CalCloudValueLen(Type &cloudValue, uint32_t &totalSize)
134 {
135     switch (cloudValue.index()) {
136         case TYPE_INDEX<int64_t>:
137             totalSize += sizeof(int64_t);
138             break;
139         case TYPE_INDEX<double>:
140             totalSize += sizeof(double);
141             break;
142         case TYPE_INDEX<std::string>:
143             totalSize += std::get<std::string>(cloudValue).size();
144             break;
145         case TYPE_INDEX<bool>:
146             totalSize += sizeof(int32_t);
147             break;
148         case TYPE_INDEX<Bytes>:
149         case TYPE_INDEX<Asset>:
150         case TYPE_INDEX<Assets>:
151             totalSize += std::get<Bytes>(cloudValue).size();
152             break;
153         default: {
154             break;
155         }
156     }
157 }
158 } // namespace DistributedDB