statement.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  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. #include "sql/statement.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include "base/containers/span.h"
  8. #include "base/dcheck_is_on.h"
  9. #include "base/logging.h"
  10. #include "base/numerics/safe_conversions.h"
  11. #include "base/sequence_checker.h"
  12. #include "base/strings/string_piece.h"
  13. #include "base/strings/string_util.h"
  14. #include "base/strings/utf_string_conversions.h"
  15. #include "base/time/time.h"
  16. #include "sql/sqlite_result_code.h"
  17. #include "sql/sqlite_result_code_values.h"
  18. #include "third_party/sqlite/sqlite3.h"
  19. namespace sql {
  20. // This empty constructor initializes our reference with an empty one so that
  21. // we don't have to null-check the ref_ to see if the statement is valid: we
  22. // only have to check the ref's validity bit.
  23. Statement::Statement()
  24. : ref_(base::MakeRefCounted<Database::StatementRef>(nullptr,
  25. nullptr,
  26. false)) {}
  27. Statement::Statement(scoped_refptr<Database::StatementRef> ref)
  28. : ref_(std::move(ref)) {}
  29. Statement::~Statement() {
  30. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  31. // Free the resources associated with this statement. We assume there's only
  32. // one statement active for a given sqlite3_stmt at any time, so this won't
  33. // mess with anything.
  34. Reset(true);
  35. }
  36. void Statement::Assign(scoped_refptr<Database::StatementRef> ref) {
  37. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  38. Reset(true);
  39. ref_ = std::move(ref);
  40. }
  41. void Statement::Clear() {
  42. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  43. Assign(base::MakeRefCounted<Database::StatementRef>(nullptr, nullptr, false));
  44. succeeded_ = false;
  45. }
  46. bool Statement::CheckValid() const {
  47. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  48. // Allow operations to fail silently if a statement was invalidated
  49. // because the database was closed by an error handler.
  50. DLOG_IF(FATAL, !ref_->was_valid())
  51. << "Cannot call mutating statements on an invalid statement.";
  52. return is_valid();
  53. }
  54. SqliteResultCode Statement::StepInternal() {
  55. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  56. if (!CheckValid())
  57. return SqliteResultCode::kError;
  58. absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
  59. ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
  60. auto sqlite_result_code = ToSqliteResultCode(sqlite3_step(ref_->stmt()));
  61. return CheckSqliteResultCode(sqlite_result_code);
  62. }
  63. bool Statement::Run() {
  64. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  65. #if DCHECK_IS_ON()
  66. DCHECK(!run_called_) << "Run() must be called exactly once";
  67. run_called_ = true;
  68. DCHECK(!step_called_) << "Run() must not be mixed with Step()";
  69. #endif // DCHECK_IS_ON()
  70. return StepInternal() == SqliteResultCode::kDone;
  71. }
  72. bool Statement::Step() {
  73. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  74. #if DCHECK_IS_ON()
  75. DCHECK(!run_called_) << "Run() must not be mixed with Step()";
  76. step_called_ = true;
  77. #endif // DCHECK_IS_ON()
  78. return StepInternal() == SqliteResultCode::kRow;
  79. }
  80. void Statement::Reset(bool clear_bound_vars) {
  81. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  82. absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
  83. ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
  84. if (is_valid()) {
  85. if (clear_bound_vars)
  86. sqlite3_clear_bindings(ref_->stmt());
  87. // StepInternal() cannot track success because statements may be reset
  88. // before reaching SQLITE_DONE. Don't call CheckError() because
  89. // sqlite3_reset() returns the last step error, which StepInternal() already
  90. // checked.
  91. sqlite3_reset(ref_->stmt());
  92. }
  93. // Potentially release dirty cache pages if an autocommit statement made
  94. // changes.
  95. if (ref_->database())
  96. ref_->database()->ReleaseCacheMemoryIfNeeded(false);
  97. succeeded_ = false;
  98. #if DCHECK_IS_ON()
  99. run_called_ = false;
  100. step_called_ = false;
  101. #endif // DCHECK_IS_ON()
  102. }
  103. bool Statement::Succeeded() const {
  104. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  105. return is_valid() && succeeded_;
  106. }
  107. void Statement::BindNull(int param_index) {
  108. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  109. #if DCHECK_IS_ON()
  110. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  111. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  112. #endif // DCHECK_IS_ON()
  113. if (!is_valid())
  114. return;
  115. DCHECK_GE(param_index, 0);
  116. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  117. << "Invalid parameter index";
  118. int sqlite_result_code = sqlite3_bind_null(ref_->stmt(), param_index + 1);
  119. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  120. }
  121. void Statement::BindBool(int param_index, bool val) {
  122. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  123. return BindInt64(param_index, val ? 1 : 0);
  124. }
  125. void Statement::BindInt(int param_index, int val) {
  126. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  127. #if DCHECK_IS_ON()
  128. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  129. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  130. #endif // DCHECK_IS_ON()
  131. if (!is_valid())
  132. return;
  133. DCHECK_GE(param_index, 0);
  134. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  135. << "Invalid parameter index";
  136. int sqlite_result_code = sqlite3_bind_int(ref_->stmt(), param_index + 1, val);
  137. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  138. }
  139. void Statement::BindInt64(int param_index, int64_t val) {
  140. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  141. #if DCHECK_IS_ON()
  142. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  143. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  144. #endif // DCHECK_IS_ON()
  145. if (!is_valid())
  146. return;
  147. DCHECK_GE(param_index, 0);
  148. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  149. << "Invalid parameter index";
  150. int sqlite_result_code =
  151. sqlite3_bind_int64(ref_->stmt(), param_index + 1, val);
  152. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  153. }
  154. void Statement::BindDouble(int param_index, double val) {
  155. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  156. #if DCHECK_IS_ON()
  157. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  158. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  159. #endif // DCHECK_IS_ON()
  160. if (!is_valid())
  161. return;
  162. DCHECK_GE(param_index, 0);
  163. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  164. << "Invalid parameter index";
  165. int sqlite_result_code =
  166. sqlite3_bind_double(ref_->stmt(), param_index + 1, val);
  167. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  168. }
  169. void Statement::BindTime(int param_index, base::Time val) {
  170. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  171. #if DCHECK_IS_ON()
  172. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  173. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  174. #endif // DCHECK_IS_ON()
  175. if (!is_valid())
  176. return;
  177. DCHECK_GE(param_index, 0);
  178. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  179. << "Invalid parameter index";
  180. int64_t int_value = val.ToDeltaSinceWindowsEpoch().InMicroseconds();
  181. int sqlite_result_code =
  182. sqlite3_bind_int64(ref_->stmt(), param_index + 1, int_value);
  183. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  184. }
  185. void Statement::BindCString(int param_index, const char* val) {
  186. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  187. #if DCHECK_IS_ON()
  188. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  189. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  190. #endif // DCHECK_IS_ON()
  191. DCHECK(val);
  192. if (!is_valid())
  193. return;
  194. DCHECK_GE(param_index, 0);
  195. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  196. << "Invalid parameter index";
  197. // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  198. // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  199. //
  200. // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  201. // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  202. // issue.
  203. int sqlite_result_code = sqlite3_bind_text(ref_->stmt(), param_index + 1, val,
  204. -1, SQLITE_TRANSIENT);
  205. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  206. }
  207. void Statement::BindString(int param_index, base::StringPiece value) {
  208. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  209. #if DCHECK_IS_ON()
  210. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  211. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  212. #endif // DCHECK_IS_ON()
  213. if (!is_valid())
  214. return;
  215. DCHECK_GE(param_index, 0);
  216. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  217. << "Invalid parameter index";
  218. // base::StringPiece::data() may return null for empty pieces. In particular,
  219. // this may happen when the StringPiece is created from the default
  220. // constructor.
  221. //
  222. // However, sqlite3_bind_text() always interprets a nullptr data argument as a
  223. // NULL value, instead of an empty BLOB value.
  224. static constexpr char kEmptyPlaceholder[] = {0x00};
  225. const char* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;
  226. // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  227. // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  228. //
  229. // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  230. // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  231. // issue.
  232. int sqlite_result_code = sqlite3_bind_text(
  233. ref_->stmt(), param_index + 1, data, value.size(), SQLITE_TRANSIENT);
  234. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  235. }
  236. void Statement::BindString16(int param_index, base::StringPiece16 value) {
  237. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  238. return BindString(param_index, base::UTF16ToUTF8(value));
  239. }
  240. void Statement::BindBlob(int param_index, base::span<const uint8_t> value) {
  241. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  242. #if DCHECK_IS_ON()
  243. DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  244. DCHECK(!step_called_) << __func__ << " must not be called after Step()";
  245. #endif // DCHECK_IS_ON()
  246. if (!is_valid())
  247. return;
  248. DCHECK_GE(param_index, 0);
  249. DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
  250. << "Invalid parameter index";
  251. // span::data() may return null for empty spans. In particular, this may
  252. // happen when the span is created out of a std::vector, because
  253. // std::vector::data() may (or may not) return null for empty vectors.
  254. //
  255. // However, sqlite3_bind_blob() always interprets a nullptr data argument as a
  256. // NULL value, instead of an empty BLOB value.
  257. //
  258. // While the difference between NULL and an empty BLOB may not matter in some
  259. // cases, it may also cause subtle bugs in other cases. So, we cannot pass
  260. // span.data() directly to sqlite3_bind_blob().
  261. static constexpr uint8_t kEmptyPlaceholder[] = {0x00};
  262. const uint8_t* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;
  263. // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  264. // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  265. //
  266. // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  267. // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  268. // issue.
  269. int sqlite_result_code = sqlite3_bind_blob(
  270. ref_->stmt(), param_index + 1, data, value.size(), SQLITE_TRANSIENT);
  271. DCHECK_EQ(sqlite_result_code, SQLITE_OK);
  272. }
  273. int Statement::ColumnCount() const {
  274. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  275. if (!is_valid())
  276. return 0;
  277. return sqlite3_column_count(ref_->stmt());
  278. }
  279. // Verify that our enum matches sqlite's values.
  280. static_assert(static_cast<int>(ColumnType::kInteger) == SQLITE_INTEGER,
  281. "INTEGER mismatch");
  282. static_assert(static_cast<int>(ColumnType::kFloat) == SQLITE_FLOAT,
  283. "FLOAT mismatch");
  284. static_assert(static_cast<int>(ColumnType::kText) == SQLITE_TEXT,
  285. "TEXT mismatch");
  286. static_assert(static_cast<int>(ColumnType::kBlob) == SQLITE_BLOB,
  287. "BLOB mismatch");
  288. static_assert(static_cast<int>(ColumnType::kNull) == SQLITE_NULL,
  289. "NULL mismatch");
  290. ColumnType Statement::GetColumnType(int col) {
  291. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  292. #if DCHECK_IS_ON()
  293. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  294. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  295. #endif // DCHECK_IS_ON()
  296. return static_cast<enum ColumnType>(sqlite3_column_type(ref_->stmt(), col));
  297. }
  298. bool Statement::ColumnBool(int column_index) {
  299. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  300. return static_cast<bool>(ColumnInt64(column_index));
  301. }
  302. int Statement::ColumnInt(int column_index) {
  303. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  304. #if DCHECK_IS_ON()
  305. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  306. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  307. #endif // DCHECK_IS_ON()
  308. if (!CheckValid())
  309. return 0;
  310. DCHECK_GE(column_index, 0);
  311. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  312. << "Invalid column index";
  313. return sqlite3_column_int(ref_->stmt(), column_index);
  314. }
  315. int64_t Statement::ColumnInt64(int column_index) {
  316. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  317. #if DCHECK_IS_ON()
  318. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  319. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  320. #endif // DCHECK_IS_ON()
  321. if (!CheckValid())
  322. return 0;
  323. DCHECK_GE(column_index, 0);
  324. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  325. << "Invalid column index";
  326. return sqlite3_column_int64(ref_->stmt(), column_index);
  327. }
  328. double Statement::ColumnDouble(int column_index) {
  329. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  330. #if DCHECK_IS_ON()
  331. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  332. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  333. #endif // DCHECK_IS_ON()
  334. if (!CheckValid())
  335. return 0;
  336. DCHECK_GE(column_index, 0);
  337. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  338. << "Invalid column index";
  339. return sqlite3_column_double(ref_->stmt(), column_index);
  340. }
  341. base::Time Statement::ColumnTime(int column_index) {
  342. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  343. #if DCHECK_IS_ON()
  344. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  345. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  346. #endif // DCHECK_IS_ON()
  347. if (!CheckValid())
  348. return base::Time();
  349. DCHECK_GE(column_index, 0);
  350. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  351. << "Invalid column index";
  352. int64_t int_value = sqlite3_column_int64(ref_->stmt(), column_index);
  353. return base::Time::FromDeltaSinceWindowsEpoch(base::Microseconds(int_value));
  354. }
  355. std::string Statement::ColumnString(int column_index) {
  356. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  357. #if DCHECK_IS_ON()
  358. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  359. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  360. #endif // DCHECK_IS_ON()
  361. if (!CheckValid())
  362. return std::string();
  363. DCHECK_GE(column_index, 0);
  364. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  365. << "Invalid column index";
  366. const char* string_buffer = reinterpret_cast<const char*>(
  367. sqlite3_column_text(ref_->stmt(), column_index));
  368. int size = sqlite3_column_bytes(ref_->stmt(), column_index);
  369. std::string result;
  370. if (string_buffer && size > 0)
  371. result.assign(string_buffer, size);
  372. return result;
  373. }
  374. std::u16string Statement::ColumnString16(int column_index) {
  375. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  376. #if DCHECK_IS_ON()
  377. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  378. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  379. #endif // DCHECK_IS_ON()
  380. if (!CheckValid())
  381. return std::u16string();
  382. DCHECK_GE(column_index, 0);
  383. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  384. << "Invalid column index";
  385. std::string string = ColumnString(column_index);
  386. return string.empty() ? std::u16string() : base::UTF8ToUTF16(string);
  387. }
  388. base::span<const uint8_t> Statement::ColumnBlob(int column_index) {
  389. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  390. #if DCHECK_IS_ON()
  391. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  392. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  393. #endif // DCHECK_IS_ON()
  394. if (!CheckValid())
  395. return base::span<const uint8_t>();
  396. DCHECK_GE(column_index, 0);
  397. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  398. << "Invalid column index";
  399. int result_size = sqlite3_column_bytes(ref_->stmt(), column_index);
  400. const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  401. DCHECK(result_size == 0 || result_buffer != nullptr)
  402. << "sqlite3_column_blob() returned a null buffer for a non-empty BLOB";
  403. return base::make_span(static_cast<const uint8_t*>(result_buffer),
  404. result_size);
  405. }
  406. bool Statement::ColumnBlobAsString(int column_index, std::string* result) {
  407. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  408. #if DCHECK_IS_ON()
  409. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  410. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  411. #endif // DCHECK_IS_ON()
  412. if (!CheckValid())
  413. return false;
  414. DCHECK_GE(column_index, 0);
  415. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  416. << "Invalid column index";
  417. const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  418. int size = sqlite3_column_bytes(ref_->stmt(), column_index);
  419. if (result_buffer && size > 0) {
  420. result->assign(reinterpret_cast<const char*>(result_buffer), size);
  421. } else {
  422. result->clear();
  423. }
  424. return true;
  425. }
  426. bool Statement::ColumnBlobAsVector(int column_index,
  427. std::vector<char>* result) {
  428. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  429. #if DCHECK_IS_ON()
  430. DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  431. DCHECK(step_called_) << __func__ << " can only be used after Step()";
  432. #endif // DCHECK_IS_ON()
  433. if (!CheckValid())
  434. return false;
  435. DCHECK_GE(column_index, 0);
  436. DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
  437. << "Invalid column index";
  438. const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  439. int size = sqlite3_column_bytes(ref_->stmt(), column_index);
  440. if (result_buffer && size > 0) {
  441. // Unlike std::string, std::vector does not have an assign() overload that
  442. // takes a buffer and a size.
  443. result->assign(static_cast<const char*>(result_buffer),
  444. static_cast<const char*>(result_buffer) + size);
  445. } else {
  446. result->clear();
  447. }
  448. return true;
  449. }
  450. bool Statement::ColumnBlobAsVector(int column_index,
  451. std::vector<uint8_t>* result) {
  452. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  453. return ColumnBlobAsVector(column_index,
  454. reinterpret_cast<std::vector<char>*>(result));
  455. }
  456. std::string Statement::GetSQLStatement() {
  457. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  458. // SQLite promises to keep the returned buffer alive until the statement is
  459. // finalized. We immediately copy the buffer contents into a std::string so we
  460. // don't need to worry about its lifetime. The performance overhead is
  461. // acceptable because this method should only be invoked for logging details
  462. // about SQLite errors.
  463. //
  464. // We use sqlite3_sql() instead of sqlite3_expanded_sql() because:
  465. // - The returned SQL string matches the source code, making it easy to
  466. // search.
  467. // - This works with SQL statements that work with large data, such as BLOBS
  468. // storing images.
  469. // - The returned string is free of bound values, so it does not contain any
  470. // PII that would raise privacy concerns around logging.
  471. //
  472. // Do not change this to use sqlite3_expanded_sql(). If that need ever arises
  473. // in the future, make a new function instead listing the above caveats.
  474. //
  475. // See https://www.sqlite.org/c3ref/expanded_sql.html for more details on the
  476. // difference between sqlite3_sql() and sqlite3_expanded_sql().
  477. return sqlite3_sql(ref_->stmt());
  478. }
  479. SqliteResultCode Statement::CheckSqliteResultCode(
  480. SqliteResultCode sqlite_result_code) {
  481. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  482. succeeded_ = IsSqliteSuccessCode(sqlite_result_code);
  483. if (!succeeded_ && ref_.get() && ref_->database()) {
  484. auto sqlite_error_code = ToSqliteErrorCode(sqlite_result_code);
  485. ref_->database()->OnSqliteError(sqlite_error_code, this, nullptr);
  486. }
  487. return sqlite_result_code;
  488. }
  489. } // namespace sql