~singpolyma/biboumi

ref: ba61d2034058818fe76cef6b23f311259d37b3fe biboumi/src/database/query.hpp -rw-r--r-- 2.5 KiB
ba61d203 — louiz’ Empty the <command/> nodes before reusing them in our responses 4 years ago
                                                                                
50cadf3d louiz’
7e64a2e3 louiz’
40db183e louiz’
9defd0cc louiz’
34ed2cc1 louiz’
9defd0cc louiz’
50cadf3d louiz’
0168b96b louiz’
dbb86bcc louiz’
d0e3c71b louiz’
dbb86bcc louiz’
03714c6c louiz’
0168b96b louiz’
7e64a2e3 louiz’
50cadf3d louiz’
0168b96b louiz’
50cadf3d louiz’
7e64a2e3 louiz’
50cadf3d louiz’
d0e3c71b louiz’
50cadf3d louiz’
d0e3c71b louiz’
03714c6c louiz’
d0e3c71b louiz’
61de6b1d louiz’
d0e3c71b louiz’
61de6b1d louiz’
d0e3c71b louiz’
b71ca15a louiz’
d0e3c71b louiz’
b71ca15a louiz’
d0e3c71b louiz’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#pragma once

#include <biboumi.h>

#include <utils/optional_bool.hpp>
#include <database/statement.hpp>
#include <database/column.hpp>

#include <logger/logger.hpp>

#include <vector>
#include <string>

void actual_bind(Statement& statement, const std::string& value, int index);
void actual_bind(Statement& statement, const std::int64_t& value, int index);
template <typename T, typename std::enable_if_t<std::is_integral<T>::value>* = 0>
void actual_bind(Statement& statement, const T& value, int index)
{
  actual_bind(statement, static_cast<std::int64_t>(value), index);
}
void actual_bind(Statement& statement, const OptionalBool& value, int index);

#ifdef DEBUG_SQL_QUERIES
#include <utils/scopetimer.hpp>

inline auto make_sql_timer()
{
  return make_scope_timer([](const std::chrono::steady_clock::duration& elapsed)
                          {
                            const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(elapsed);
                            const auto rest = elapsed - seconds;
                            log_debug("Query executed in ", seconds.count(), ".", rest.count(), "s.");
                          });
}
#endif

struct Query
{
    std::string body;
    std::vector<std::string> params;
    int current_param{1};

    Query(std::string str):
        body(std::move(str))
    {}

#ifdef DEBUG_SQL_QUERIES
    auto log_and_time()
    {
       std::ostringstream os;
       os << this->body << "; ";
       for (const auto& param: this->params)
         os << "'" << param << "' ";
       log_debug("SQL QUERY: ", os.str());
       return make_sql_timer();
    }
#endif
};

template <typename ColumnType>
void add_param(Query& query, const ColumnType& column)
{
  std::cout << "add_param<ColumnType>" << std::endl;
  actual_add_param(query, column.value);
}

template <typename T>
void actual_add_param(Query& query, const T& val)
{
  query.params.push_back(std::to_string(val));
}

void actual_add_param(Query& query, const std::string& val);
void actual_add_param(Query& query, const OptionalBool& val);

template <typename T>
typename std::enable_if<!std::is_integral<T>::value, Query&>::type
operator<<(Query& query, const T&)
{
  query.body += T::name;
  return query;
}

Query& operator<<(Query& query, const char* str);
Query& operator<<(Query& query, const std::string& str);
template <typename Integer>
typename std::enable_if<std::is_integral<Integer>::value, Query&>::type
operator<<(Query& query, const Integer& i)
{
  query.body += "$" + std::to_string(query.current_param++);
  actual_add_param(query, i);
  return query;
}