[M85 Migration] Add an evas gl option for rotation
[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() {
57   if (!CheckValid())
58     return SQLITE_ERROR;
59
60   base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
61   ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
62
63   stepped_ = true;
64   int ret = sqlite3_step(ref_->stmt());
65   return CheckError(ret);
66 }
67
68 bool Statement::Run() {
69   DCHECK(!stepped_);
70   return StepInternal() == SQLITE_DONE;
71 }
72
73 bool Statement::Step() {
74   return StepInternal() == SQLITE_ROW;
75 }
76
77 void Statement::Reset(bool clear_bound_vars) {
78   base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
79   ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
80   if (is_valid()) {
81     if (clear_bound_vars)
82       sqlite3_clear_bindings(ref_->stmt());
83
84     // StepInternal() cannot track success because statements may be reset
85     // before reaching SQLITE_DONE.  Don't call CheckError() because
86     // sqlite3_reset() returns the last step error, which StepInternal() already
87     // checked.
88     sqlite3_reset(ref_->stmt());
89   }
90
91   // Potentially release dirty cache pages if an autocommit statement made
92   // changes.
93   if (ref_->database())
94     ref_->database()->ReleaseCacheMemoryIfNeeded(false);
95
96   succeeded_ = false;
97   stepped_ = false;
98 }
99
100 bool Statement::Succeeded() const {
101   return is_valid() && succeeded_;
102 }
103
104 bool Statement::BindNull(int col) {
105   DCHECK(!stepped_);
106
107   return is_valid() && CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
108 }
109
110 bool Statement::BindBool(int col, bool val) {
111   return BindInt(col, val ? 1 : 0);
112 }
113
114 bool Statement::BindInt(int col, int val) {
115   DCHECK(!stepped_);
116
117   return is_valid() && CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
118 }
119
120 bool Statement::BindInt64(int col, int64_t val) {
121   DCHECK(!stepped_);
122
123   return is_valid() && CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
124 }
125
126 bool Statement::BindDouble(int col, double val) {
127   DCHECK(!stepped_);
128
129   return is_valid() && CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
130 }
131
132 bool Statement::BindCString(int col, const char* val) {
133   DCHECK(!stepped_);
134
135   return is_valid() && CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
136                                                  SQLITE_TRANSIENT));
137 }
138
139 bool Statement::BindString(int col, const std::string& val) {
140   DCHECK(!stepped_);
141
142   return is_valid() &&
143          CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(),
144                                    base::checked_cast<int>(val.size()),
145                                    SQLITE_TRANSIENT));
146 }
147
148 bool Statement::BindString16(int col, const base::string16& value) {
149   return BindString(col, base::UTF16ToUTF8(value));
150 }
151
152 bool Statement::BindBlob(int col, const void* val, int val_len) {
153   DCHECK(!stepped_);
154
155   return is_valid() && CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, val,
156                                                  val_len, SQLITE_TRANSIENT));
157 }
158
159 int Statement::ColumnCount() const {
160   if (!is_valid())
161     return 0;
162   return sqlite3_column_count(ref_->stmt());
163 }
164
165 // Verify that our enum matches sqlite's values.
166 static_assert(static_cast<int>(ColumnType::kInteger) == SQLITE_INTEGER,
167               "INTEGER mismatch");
168 static_assert(static_cast<int>(ColumnType::kFloat) == SQLITE_FLOAT,
169               "FLOAT mismatch");
170 static_assert(static_cast<int>(ColumnType::kText) == SQLITE_TEXT,
171               "TEXT mismatch");
172 static_assert(static_cast<int>(ColumnType::kBlob) == SQLITE_BLOB,
173               "BLOB mismatch");
174 static_assert(static_cast<int>(ColumnType::kNull) == SQLITE_NULL,
175               "NULL mismatch");
176
177 ColumnType Statement::GetColumnType(int col) const {
178   return static_cast<enum ColumnType>(sqlite3_column_type(ref_->stmt(), col));
179 }
180
181 bool Statement::ColumnBool(int col) const {
182   return static_cast<bool>(ColumnInt(col));
183 }
184
185 int Statement::ColumnInt(int col) const {
186   if (!CheckValid())
187     return 0;
188   return sqlite3_column_int(ref_->stmt(), col);
189 }
190
191 int64_t Statement::ColumnInt64(int col) const {
192   if (!CheckValid())
193     return 0;
194   return sqlite3_column_int64(ref_->stmt(), col);
195 }
196
197 double Statement::ColumnDouble(int col) const {
198   if (!CheckValid())
199     return 0;
200   return sqlite3_column_double(ref_->stmt(), col);
201 }
202
203 std::string Statement::ColumnString(int col) const {
204   if (!CheckValid())
205     return std::string();
206
207   const char* str = reinterpret_cast<const char*>(
208       sqlite3_column_text(ref_->stmt(), col));
209   int len = sqlite3_column_bytes(ref_->stmt(), col);
210
211   std::string result;
212   if (str && len > 0)
213     result.assign(str, len);
214   return result;
215 }
216
217 base::string16 Statement::ColumnString16(int col) const {
218   if (!CheckValid())
219     return base::string16();
220
221   std::string s = ColumnString(col);
222   return !s.empty() ? base::UTF8ToUTF16(s) : base::string16();
223 }
224
225 int Statement::ColumnByteLength(int col) const {
226   if (!CheckValid())
227     return 0;
228   return sqlite3_column_bytes(ref_->stmt(), col);
229 }
230
231 const void* Statement::ColumnBlob(int col) const {
232   if (!CheckValid())
233     return nullptr;
234
235   return sqlite3_column_blob(ref_->stmt(), col);
236 }
237
238 bool Statement::ColumnBlobAsString(int col, std::string* blob) const {
239   if (!CheckValid())
240     return false;
241
242   const void* p = ColumnBlob(col);
243   size_t len = ColumnByteLength(col);
244   blob->resize(len);
245   if (blob->size() != len) {
246     return false;
247   }
248   blob->assign(reinterpret_cast<const char*>(p), len);
249   return true;
250 }
251
252 bool Statement::ColumnBlobAsString16(int col, base::string16* val) const {
253   if (!CheckValid())
254     return false;
255
256   const void* data = ColumnBlob(col);
257   size_t len = ColumnByteLength(col) / sizeof(base::char16);
258   val->resize(len);
259   if (val->size() != len)
260     return false;
261   val->assign(reinterpret_cast<const base::char16*>(data), len);
262   return true;
263 }
264
265 bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
266   val->clear();
267
268   if (!CheckValid())
269     return false;
270
271   const void* data = sqlite3_column_blob(ref_->stmt(), col);
272   int len = sqlite3_column_bytes(ref_->stmt(), col);
273   if (data && len > 0) {
274     val->resize(len);
275     memcpy(&(*val)[0], data, len);
276   }
277   return true;
278 }
279
280 bool Statement::ColumnBlobAsVector(
281     int col,
282     std::vector<unsigned char>* val) const {
283   return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
284 }
285
286 const char* Statement::GetSQLStatement() {
287   return sqlite3_sql(ref_->stmt());
288 }
289
290 bool Statement::CheckOk(int err) const {
291   // Binding to a non-existent variable is evidence of a serious error.
292   // TODO(gbillock,shess): make this invalidate the statement so it
293   // can't wreak havoc.
294   DCHECK_NE(err, SQLITE_RANGE) << "Bind value out of range";
295   return err == SQLITE_OK;
296 }
297
298 int Statement::CheckError(int err) {
299   // Please don't add DCHECKs here, OnSqliteError() already has them.
300   succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
301   if (!succeeded_ && ref_.get() && ref_->database())
302     return ref_->database()->OnSqliteError(err, this, nullptr);
303   return err;
304 }
305
306 }  // namespace sql