Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / sql / statement.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "sql/statement.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include "base/logging.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "third_party/sqlite/sqlite3.h"
15
16 namespace sql {
17
18 // This empty constructor initializes our reference with an empty one so that
19 // we don't have to null-check the ref_ to see if the statement is valid: we
20 // only have to check the ref's validity bit.
21 Statement::Statement()
22     : ref_(base::MakeRefCounted<Database::StatementRef>(nullptr,
23                                                         nullptr,
24                                                         false)),
25       stepped_(false),
26       succeeded_(false) {}
27
28 Statement::Statement(scoped_refptr<Database::StatementRef> ref)
29     : ref_(std::move(ref)), stepped_(false), succeeded_(false) {}
30
31 Statement::~Statement() {
32   // Free the resources associated with this statement. We assume there's only
33   // one statement active for a given sqlite3_stmt at any time, so this won't
34   // mess with anything.
35   Reset(true);
36 }
37
38 void Statement::Assign(scoped_refptr<Database::StatementRef> ref) {
39   Reset(true);
40   ref_ = std::move(ref);
41 }
42
43 void Statement::Clear() {
44   Assign(base::MakeRefCounted<Database::StatementRef>(nullptr, nullptr, false));
45   succeeded_ = false;
46 }
47
48 bool Statement::CheckValid() const {
49   // Allow operations to fail silently if a statement was invalidated
50   // because the database was closed by an error handler.
51   DLOG_IF(FATAL, !ref_->was_valid())
52       << "Cannot call mutating statements on an invalid statement.";
53   return is_valid();
54 }
55
56 int Statement::StepInternal(bool timer_flag) {
57   ref_->AssertIOAllowed();
58   if (!CheckValid())
59     return SQLITE_ERROR;
60
61   const bool was_stepped = stepped_;
62   stepped_ = true;
63   int ret = SQLITE_ERROR;
64   if (!ref_->database()) {
65     ret = sqlite3_step(ref_->stmt());
66   } else {
67     if (!timer_flag) {
68       ret = sqlite3_step(ref_->stmt());
69     } else {
70       const base::TimeTicks before = ref_->database()->NowTicks();
71       ret = sqlite3_step(ref_->stmt());
72       const base::TimeTicks after = ref_->database()->NowTicks();
73       const bool read_only = !!sqlite3_stmt_readonly(ref_->stmt());
74       ref_->database()->RecordTimeAndChanges(after - before, read_only);
75     }
76
77     if (!was_stepped)
78       ref_->database()->RecordOneEvent(Database::EVENT_STATEMENT_RUN);
79
80     if (ret == SQLITE_ROW)
81       ref_->database()->RecordOneEvent(Database::EVENT_STATEMENT_ROWS);
82   }
83   return CheckError(ret);
84 }
85
86 bool Statement::Run() {
87   DCHECK(!stepped_);
88   return StepInternal(true) == SQLITE_DONE;
89 }
90
91 bool Statement::RunWithoutTimers() {
92   DCHECK(!stepped_);
93   return StepInternal(false) == SQLITE_DONE;
94 }
95
96 bool Statement::Step() {
97   return StepInternal(true) == SQLITE_ROW;
98 }
99
100 void Statement::Reset(bool clear_bound_vars) {
101   ref_->AssertIOAllowed();
102   if (is_valid()) {
103     if (clear_bound_vars)
104       sqlite3_clear_bindings(ref_->stmt());
105
106     // StepInternal() cannot track success because statements may be reset
107     // before reaching SQLITE_DONE.  Don't call CheckError() because
108     // sqlite3_reset() returns the last step error, which StepInternal() already
109     // checked.
110     const int rc =sqlite3_reset(ref_->stmt());
111     if (rc == SQLITE_OK && ref_->database())
112       ref_->database()->RecordOneEvent(Database::EVENT_STATEMENT_SUCCESS);
113   }
114
115   // Potentially release dirty cache pages if an autocommit statement made
116   // changes.
117   if (ref_->database())
118     ref_->database()->ReleaseCacheMemoryIfNeeded(false);
119
120   succeeded_ = false;
121   stepped_ = false;
122 }
123
124 bool Statement::Succeeded() const {
125   return is_valid() && succeeded_;
126 }
127
128 bool Statement::BindNull(int col) {
129   DCHECK(!stepped_);
130
131   return is_valid() && CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
132 }
133
134 bool Statement::BindBool(int col, bool val) {
135   return BindInt(col, val ? 1 : 0);
136 }
137
138 bool Statement::BindInt(int col, int val) {
139   DCHECK(!stepped_);
140
141   return is_valid() && CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
142 }
143
144 bool Statement::BindInt64(int col, int64_t val) {
145   DCHECK(!stepped_);
146
147   return is_valid() && CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
148 }
149
150 bool Statement::BindDouble(int col, double val) {
151   DCHECK(!stepped_);
152
153   return is_valid() && CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
154 }
155
156 bool Statement::BindCString(int col, const char* val) {
157   DCHECK(!stepped_);
158
159   return is_valid() && CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
160                                                  SQLITE_TRANSIENT));
161 }
162
163 bool Statement::BindString(int col, const std::string& val) {
164   DCHECK(!stepped_);
165
166   return is_valid() &&
167          CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(),
168                                    base::checked_cast<int>(val.size()),
169                                    SQLITE_TRANSIENT));
170 }
171
172 bool Statement::BindString16(int col, const base::string16& value) {
173   return BindString(col, base::UTF16ToUTF8(value));
174 }
175
176 bool Statement::BindBlob(int col, const void* val, int val_len) {
177   DCHECK(!stepped_);
178
179   return is_valid() && CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, val,
180                                                  val_len, SQLITE_TRANSIENT));
181 }
182
183 int Statement::ColumnCount() const {
184   if (!is_valid())
185     return 0;
186   return sqlite3_column_count(ref_->stmt());
187 }
188
189 // Verify that our enum matches sqlite's values.
190 static_assert(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, "integer no match");
191 static_assert(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, "float no match");
192 static_assert(COLUMN_TYPE_TEXT == SQLITE_TEXT, "integer no match");
193 static_assert(COLUMN_TYPE_BLOB == SQLITE_BLOB, "blob no match");
194 static_assert(COLUMN_TYPE_NULL == SQLITE_NULL, "null no match");
195
196 ColType Statement::ColumnType(int col) const {
197   return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
198 }
199
200 bool Statement::ColumnBool(int col) const {
201   return static_cast<bool>(ColumnInt(col));
202 }
203
204 int Statement::ColumnInt(int col) const {
205   if (!CheckValid())
206     return 0;
207   return sqlite3_column_int(ref_->stmt(), col);
208 }
209
210 int64_t Statement::ColumnInt64(int col) const {
211   if (!CheckValid())
212     return 0;
213   return sqlite3_column_int64(ref_->stmt(), col);
214 }
215
216 double Statement::ColumnDouble(int col) const {
217   if (!CheckValid())
218     return 0;
219   return sqlite3_column_double(ref_->stmt(), col);
220 }
221
222 std::string Statement::ColumnString(int col) const {
223   if (!CheckValid())
224     return std::string();
225
226   const char* str = reinterpret_cast<const char*>(
227       sqlite3_column_text(ref_->stmt(), col));
228   int len = sqlite3_column_bytes(ref_->stmt(), col);
229
230   std::string result;
231   if (str && len > 0)
232     result.assign(str, len);
233   return result;
234 }
235
236 base::string16 Statement::ColumnString16(int col) const {
237   if (!CheckValid())
238     return base::string16();
239
240   std::string s = ColumnString(col);
241   return !s.empty() ? base::UTF8ToUTF16(s) : base::string16();
242 }
243
244 int Statement::ColumnByteLength(int col) const {
245   if (!CheckValid())
246     return 0;
247   return sqlite3_column_bytes(ref_->stmt(), col);
248 }
249
250 const void* Statement::ColumnBlob(int col) const {
251   if (!CheckValid())
252     return nullptr;
253
254   return sqlite3_column_blob(ref_->stmt(), col);
255 }
256
257 bool Statement::ColumnBlobAsString(int col, std::string* blob) const {
258   if (!CheckValid())
259     return false;
260
261   const void* p = ColumnBlob(col);
262   size_t len = ColumnByteLength(col);
263   blob->resize(len);
264   if (blob->size() != len) {
265     return false;
266   }
267   blob->assign(reinterpret_cast<const char*>(p), len);
268   return true;
269 }
270
271 bool Statement::ColumnBlobAsString16(int col, base::string16* val) const {
272   if (!CheckValid())
273     return false;
274
275   const void* data = ColumnBlob(col);
276   size_t len = ColumnByteLength(col) / sizeof(base::char16);
277   val->resize(len);
278   if (val->size() != len)
279     return false;
280   val->assign(reinterpret_cast<const base::char16*>(data), len);
281   return true;
282 }
283
284 bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
285   val->clear();
286
287   if (!CheckValid())
288     return false;
289
290   const void* data = sqlite3_column_blob(ref_->stmt(), col);
291   int len = sqlite3_column_bytes(ref_->stmt(), col);
292   if (data && len > 0) {
293     val->resize(len);
294     memcpy(&(*val)[0], data, len);
295   }
296   return true;
297 }
298
299 bool Statement::ColumnBlobAsVector(
300     int col,
301     std::vector<unsigned char>* val) const {
302   return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
303 }
304
305 const char* Statement::GetSQLStatement() {
306   return sqlite3_sql(ref_->stmt());
307 }
308
309 bool Statement::CheckOk(int err) const {
310   // Binding to a non-existent variable is evidence of a serious error.
311   // TODO(gbillock,shess): make this invalidate the statement so it
312   // can't wreak havoc.
313   DCHECK_NE(err, SQLITE_RANGE) << "Bind value out of range";
314   return err == SQLITE_OK;
315 }
316
317 int Statement::CheckError(int err) {
318   // Please don't add DCHECKs here, OnSqliteError() already has them.
319   succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
320   if (!succeeded_ && ref_.get() && ref_->database())
321     return ref_->database()->OnSqliteError(err, this, nullptr);
322   return err;
323 }
324
325 }  // namespace sql