Branch data Line data Source code
1 : : /******************************************************************************
2 : : ------------- Copyright (c) 2009-2023 H a r a l d A c h i t z ---------------
3 : : ---------- < h a r a l d dot a c h i t z at g m a i l dot c o m > ------------
4 : : ---- This Source Code Form is subject to the terms of the Mozilla Public -----
5 : : ---- License, v. 2.0. If a copy of the MPL was not distributed with this -----
6 : : ---------- file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------
7 : : ******************************************************************************/
8 : :
9 : : #include <sl3/columns.hpp>
10 : : #include <sl3/error.hpp>
11 : :
12 : : #include <cassert>
13 : : #include <sqlite3.h>
14 : :
15 : : #include "utils.hpp"
16 : :
17 : : namespace sl3
18 : : {
19 : 104 : Columns::Columns (sqlite3_stmt* stmt)
20 : 104 : : _stmt (stmt)
21 : : {
22 : 104 : }
23 : :
24 : : int
25 : 1016 : Columns::count () const
26 : : {
27 : 1016 : return sqlite3_column_count (_stmt);
28 : : }
29 : :
30 : : std::string
31 : 113 : Columns::getName (int idx) const
32 : : {
33 [ + - + + : 113 : if (idx < 0 || !(idx < count ()))
+ + ]
34 [ + - ]: 2 : throw ErrOutOfRange ("column index out of range");
35 : :
36 : 111 : const char* name = sqlite3_column_name (_stmt, idx);
37 [ + - + - : 333 : return name ? std::string (name) : std::string ();
+ - - - ]
38 : : }
39 : :
40 : : DbValue
41 : 24 : Columns::getValue (int idx) const
42 : : {
43 : 24 : return getValue (idx, Type::Variant);
44 : : }
45 : :
46 : : DbValue
47 : 190 : Columns::getValue (int idx, Type type) const
48 : : {
49 [ + - + + : 190 : if (idx < 0 || !(idx < count ()))
+ + ]
50 [ + - ]: 4 : throw ErrOutOfRange ("column index out of range");
51 : :
52 [ + + + + : 186 : switch (sqlite3_column_type (_stmt, idx))
+ - ]
53 : : {
54 : 62 : case SQLITE_INTEGER:
55 : 62 : return DbValue (getInt64 (idx), type);
56 : : break;
57 : :
58 : 34 : case SQLITE_FLOAT:
59 : 34 : return DbValue (getReal (idx), type);
60 : : break;
61 : :
62 : 67 : case SQLITE_TEXT:
63 [ + - + + ]: 69 : return DbValue (getText (idx), type);
64 : : break;
65 : :
66 : 8 : case SQLITE_BLOB:
67 [ + - + + ]: 9 : return DbValue (getBlob (idx), type);
68 : : break;
69 : :
70 : : // return this one at the end
71 : : // some compiler detect unreachable code and warn
72 : 15 : case SQLITE_NULL:
73 : : // return DbValue (type);
74 : 15 : break;
75 : :
76 : : default: // LCOV_EXCL_START
77 : : throw ErrUnexpected ("should never reach this line");
78 : : break; // LCOV_EXCL_STOP
79 : : }
80 : : // some complains non reachable code.
81 : : // therefore, handle the Null value here
82 : 15 : return DbValue (type);
83 : : }
84 : :
85 : : std::vector<std::string>
86 : 38 : Columns::getNames () const
87 : : {
88 : 38 : std::vector<std::string> names;
89 [ + - + - ]: 38 : names.reserve (as_size_t (count ()));
90 [ + - + + ]: 145 : for (int i = 0; i < count (); ++i)
91 : : {
92 [ + - + - ]: 107 : names.emplace_back (getName (i));
93 : : }
94 : :
95 : 38 : return names;
96 : 0 : }
97 : :
98 : : DbValues
99 : 1 : Columns::getRow () const
100 : : {
101 : 1 : DbValues::container_type v;
102 [ + - + + ]: 6 : for (int i = 0; i < count (); ++i)
103 : : {
104 [ + - + - ]: 5 : v.push_back (getValue (i));
105 : : }
106 : 2 : return DbValues (std::move (v));
107 : 1 : }
108 : :
109 : : DbValues
110 : 55 : Columns::getRow (const Types& types) const
111 : : {
112 [ + - + + ]: 55 : if (types.size () != static_cast<size_t> (count ()))
113 : : {
114 [ + - ]: 2 : throw ErrTypeMisMatch ("types.size () != getColumnCount ()");
115 : : }
116 : :
117 : 53 : DbValues::container_type v;
118 [ + - + + ]: 201 : for (int i = 0; i < count (); ++i)
119 : : {
120 [ + + + - ]: 150 : v.push_back (getValue (i, types[as_size_t (i)]));
121 : : }
122 : 102 : return DbValues (std::move (v));
123 : 53 : }
124 : :
125 : : Type
126 : 20 : Columns::getType (int idx) const
127 : : {
128 [ + - + + : 20 : if (idx < 0 || !(idx < count ()))
+ + ]
129 [ + - ]: 2 : throw ErrOutOfRange ("column index out of range");
130 : :
131 : 18 : auto type = Type::Variant;
132 : :
133 [ + + + + : 18 : switch (sqlite3_column_type (_stmt, idx))
+ - ]
134 : : {
135 : 6 : case SQLITE_INTEGER:
136 : 6 : type = Type::Int;
137 : 6 : break;
138 : :
139 : 2 : case SQLITE_FLOAT:
140 : 2 : type = Type::Real;
141 : 2 : break;
142 : :
143 : 6 : case SQLITE_TEXT:
144 : 6 : type = Type::Text;
145 : 6 : break;
146 : :
147 : 2 : case SQLITE_BLOB:
148 : 2 : type = Type::Blob;
149 : 2 : break;
150 : :
151 : 2 : case SQLITE_NULL:
152 : 2 : type = Type::Null;
153 : 2 : break;
154 : :
155 : 0 : default:
156 : : throw ErrUnexpected ("never reach"); // LCOV_EXCL_LINE
157 : : break; // LCOV_EXCL_LINE
158 : : }
159 : :
160 : 18 : return type;
161 : : }
162 : :
163 : : size_t
164 : 3 : Columns::getSize (int idx) const
165 : : {
166 [ + - + + : 3 : if (idx < 0 || !(idx < count ()))
+ + ]
167 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
168 : :
169 : 2 : return as_size_t (sqlite3_column_bytes (_stmt, idx));
170 : : }
171 : :
172 : : std::string
173 : 72 : Columns::getText (int idx) const
174 : : {
175 [ + - + + : 72 : if (idx < 0 || !(idx < count ()))
+ + ]
176 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
177 : :
178 : : const char* first
179 : 71 : = reinterpret_cast<const char*> (sqlite3_column_text (_stmt, idx));
180 : 71 : std::size_t s = as_size_t (sqlite3_column_bytes (_stmt, idx));
181 [ + - + - : 213 : return s > 0 ? std::string (first, s) : std::string ();
+ - - - ]
182 : : }
183 : :
184 : : int
185 : 6 : Columns::getInt (int idx) const
186 : : {
187 [ + - + + : 6 : if (idx < 0 || !(idx < count ()))
+ + ]
188 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
189 : :
190 : 5 : return sqlite3_column_int (_stmt, idx);
191 : : }
192 : :
193 : : int64_t
194 : 63 : Columns::getInt64 (int idx) const
195 : : {
196 [ + - + + : 63 : if (idx < 0 || !(idx < count ()))
+ + ]
197 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
198 : :
199 : 62 : return sqlite3_column_int64 (_stmt, idx);
200 : : }
201 : :
202 : : double
203 : 35 : Columns::getReal (int idx) const
204 : : {
205 [ + - + + : 35 : if (idx < 0 || !(idx < count ()))
+ + ]
206 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
207 : :
208 : 34 : return sqlite3_column_double (_stmt, idx);
209 : : }
210 : :
211 : : Blob
212 : 9 : Columns::getBlob (int idx) const
213 : : {
214 [ + - + + : 9 : if (idx < 0 || !(idx < count ()))
+ + ]
215 [ + - ]: 1 : throw ErrOutOfRange ("column index out of range");
216 : :
217 : : using value_type = Blob::value_type;
218 : : const value_type* first
219 : 8 : = static_cast<const value_type*> (sqlite3_column_blob (_stmt, idx));
220 : 8 : std::size_t s = as_size_t (sqlite3_column_bytes (_stmt, idx));
221 [ + - + - : 24 : return s > 0 ? Blob (first, first + s) : Blob ();
+ - - - ]
222 : : }
223 : :
224 : : } // ns
|