26#include <gnc-locale-utils.h>
29#include <dbi/dbi-dev.h>
31#include <gnc-datetime.hpp>
32#include "gnc-dbisqlresult.hpp"
33#include "gnc-dbisqlconnection.hpp"
35static QofLogModule log_module = G_LOG_DOMAIN;
37#if LIBDBI_VERSION >= 900
38#define HAVE_LIBDBI_TO_LONGLONG 1
40#define HAVE_LIBDBI_TO_LONGLONG 0
43GncDbiSqlResult::~GncDbiSqlResult()
45 int status = dbi_result_free (m_dbi_result);
50 PERR (
"Error %d in dbi_result_free() result.", m_conn->
dberror() );
55GncDbiSqlResult::dberror() const noexcept
61GncDbiSqlResult::begin()
64 if (m_dbi_result ==
nullptr ||
65 dbi_result_get_numrows(m_dbi_result) == 0)
67 int status = dbi_result_first_row(m_dbi_result);
70 int error = dberror();
72 if (error != DBI_ERROR_BADIDX)
74 PERR (
"Error %d in dbi_result_first_row()", dberror());
81GncDbiSqlResult::size() const noexcept
83 return dbi_result_get_numrows(m_dbi_result);
88GncDbiSqlResult::IteratorImpl::operator++()
90 int status = dbi_result_next_row (m_inst->m_dbi_result);
93 int error = m_inst->dberror();
94 if (error == DBI_ERROR_BADIDX || error == 0)
95 return m_inst->m_sentinel;
96 PERR(
"Error %d incrementing results iterator.", error);
98 return m_inst->m_sentinel;
101std::optional<int64_t>
102GncDbiSqlResult::IteratorImpl::get_int_at_col(
const char* col)
const
104 auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
105 if(type != DBI_TYPE_INTEGER)
107 return std::optional<int64_t>{dbi_result_get_longlong (m_inst->m_dbi_result, col)};
111GncDbiSqlResult::IteratorImpl::get_float_at_col(
const char* col)
const
113 constexpr double float_precision = 1000000.0;
114 auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
115 auto attrs = dbi_result_get_field_attribs (m_inst->m_dbi_result, col);
116 if(type != DBI_TYPE_DECIMAL ||
117 (attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE4)
119 auto locale = gnc_push_locale (LC_NUMERIC,
"C");
120 auto interim = dbi_result_get_float(m_inst->m_dbi_result, col);
121 gnc_pop_locale (LC_NUMERIC, locale);
122 double retval =
static_cast<double>(round(interim * float_precision)) / float_precision;
123 return std::optional<double>{retval};
127GncDbiSqlResult::IteratorImpl::get_double_at_col(
const char* col)
const
129 auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
130 auto attrs = dbi_result_get_field_attribs (m_inst->m_dbi_result, col);
131 if(type != DBI_TYPE_DECIMAL ||
132 (attrs & DBI_DECIMAL_SIZEMASK) != DBI_DECIMAL_SIZE8)
134 auto locale = gnc_push_locale (LC_NUMERIC,
"C");
135 auto retval = dbi_result_get_double(m_inst->m_dbi_result, col);
136 gnc_pop_locale (LC_NUMERIC, locale);
137 return std::optional<double>{retval};
140std::optional<std::string>
141GncDbiSqlResult::IteratorImpl::get_string_at_col(
const char* col)
const
143 auto type = dbi_result_get_field_type (m_inst->m_dbi_result, col);
144 dbi_result_get_field_attribs (m_inst->m_dbi_result, col);
145 if(type != DBI_TYPE_STRING)
147 auto strval = dbi_result_get_string(m_inst->m_dbi_result, col);
148 return std::optional<std::string>{strval ? strval :
""};
152GncDbiSqlResult::IteratorImpl::get_time64_at_col (
const char* col)
const
154 auto result = (dbi_result_t*) (m_inst->m_dbi_result);
155 auto type = dbi_result_get_field_type (result, col);
156 dbi_result_get_field_attribs (result, col);
157 if (type != DBI_TYPE_DATETIME)
159#if HAVE_LIBDBI_TO_LONGLONG
163 auto timeval = dbi_result_get_as_longlong(result, col);
171 auto row = dbi_result_get_currow (result);
172 auto idx = dbi_result_get_field_idx (result, col) - 1;
173 time64 timeval = result->rows[row]->field_values[idx].d_datetime;
175 if (timeval < MINTIME || timeval > MAXTIME)
177 return std::optional<time64>(timeval);
int dberror() const noexcept override
Get the connection error value.
Row of SQL Query results.
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
@ ERR_BACKEND_SERVER_ERR
error in response from server
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
#define PERR(format, args...)
Log a serious error.