1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/db/detail/RawSqliteDb.h"
10 
11 #include "td/utils/common.h"
12 #include "td/utils/logging.h"
13 #include "td/utils/ScopeGuard.h"
14 #include "td/utils/Slice.h"
15 #include "td/utils/Status.h"
16 
17 #include <memory>
18 
19 struct sqlite3;
20 struct sqlite3_stmt;
21 
22 namespace td {
23 
24 extern int VERBOSITY_NAME(sqlite);
25 
26 class SqliteStatement {
27  public:
28   SqliteStatement() = default;
29   SqliteStatement(const SqliteStatement &other) = delete;
30   SqliteStatement &operator=(const SqliteStatement &other) = delete;
31   SqliteStatement(SqliteStatement &&other) = default;
32   SqliteStatement &operator=(SqliteStatement &&other) = default;
33   ~SqliteStatement();
34 
35   Status bind_blob(int id, Slice blob) TD_WARN_UNUSED_RESULT;
36   Status bind_string(int id, Slice str) TD_WARN_UNUSED_RESULT;
37   Status bind_int32(int id, int32 value) TD_WARN_UNUSED_RESULT;
38   Status bind_int64(int id, int64 value) TD_WARN_UNUSED_RESULT;
39   Status bind_null(int id) TD_WARN_UNUSED_RESULT;
40   Status step() TD_WARN_UNUSED_RESULT;
41   Slice view_string(int id) TD_WARN_UNUSED_RESULT;
42   Slice view_blob(int id) TD_WARN_UNUSED_RESULT;
43   int32 view_int32(int id) TD_WARN_UNUSED_RESULT;
44   int64 view_int64(int id) TD_WARN_UNUSED_RESULT;
45   enum class Datatype { Integer, Float, Blob, Null, Text };
46   Datatype view_datatype(int id);
47 
48   Result<string> explain();
49 
can_step()50   bool can_step() const {
51     return state_ != State::Finish;
52   }
has_row()53   bool has_row() const {
54     return state_ == State::GotRow;
55   }
empty()56   bool empty() const {
57     return !stmt_;
58   }
59 
60   void reset();
61 
guard()62   auto guard() {
63     return ScopeExit{} + [this] {
64       this->reset();
65     };
66   }
67 
68   // TODO get row
69 
70  private:
71   friend class SqliteDb;
72   SqliteStatement(sqlite3_stmt *stmt, std::shared_ptr<detail::RawSqliteDb> db);
73 
74   class StmtDeleter {
75    public:
76     void operator()(sqlite3_stmt *stmt);
77   };
78 
79   enum class State { Start, GotRow, Finish };
80   State state_ = State::Start;
81 
82   std::unique_ptr<sqlite3_stmt, StmtDeleter> stmt_;
83   std::shared_ptr<detail::RawSqliteDb> db_;
84 
85   Status last_error();
86 };
87 
88 }  // namespace td
89