29#include <gnc-datetime.hpp>
30#include "gnc-sql-backend.hpp"
31#include "gnc-sql-object-backend.hpp"
32#include "gnc-sql-column-table-entry.hpp"
33#include "gnc-sql-result.hpp"
35static QofLogModule log_module = G_LOG_DOMAIN;
39get_autoinc_id (
void*
object,
const QofParam* param)
46set_autoinc_id (
void*
object,
void* item)
56 g_return_val_if_fail (obj_name != NULL, NULL);
58 if (m_flags & COL_AUTOINC)
60 getter = get_autoinc_id;
62 else if (m_qof_param_name != NULL)
78 if (m_flags & COL_AUTOINC)
80 setter = set_autoinc_id;
82 else if (m_qof_param_name !=
nullptr)
84 g_assert (obj_name != NULL);
97 PairVec& vec)
const noexcept
99 auto inst = get_row_value_from_object<QofInstance*>(obj_name, pObject);
100 if (inst ==
nullptr)
return;
102 if (guid !=
nullptr) {
104 vec.emplace_back (std::make_pair (std::string{m_col_name}, quote_string(guid_s)));
113 vec.emplace_back(std::move(info));
122 gpointer pObject)
const noexcept
124 g_return_if_fail (pObject != NULL);
125 g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
127 auto s = row.get_string_at_col (m_col_name);
129 set_parameter(pObject, s->c_str(), get_setter(obj_name), m_gobj_param_name);
136 vec.emplace_back(std::move(info));
144 const gpointer pObject,
145 PairVec& vec)
const noexcept
147 auto s = get_row_value_from_object<char*>(obj_name, pObject);
151 std::ostringstream stream;
153 vec.emplace_back (std::make_pair (std::string{m_col_name},
154 quote_string(stream.str())));
160typedef gint (*IntAccessFunc) (
const gpointer);
161typedef void (*IntSetterFunc) (
const gpointer, gint);
167 gpointer pObject)
const noexcept
170 g_return_if_fail (pObject != NULL);
171 g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
173 auto val = row.get_int_at_col(m_col_name);
175 set_parameter(pObject, *val,
176 reinterpret_cast<IntSetterFunc
>(get_setter(obj_name)),
184 vec.emplace_back(std::move(info));
189 const gpointer pObject,
190 PairVec& vec)
const noexcept
192 add_value_to_vec<int>(obj_name, pObject, vec);
196typedef gboolean (*BooleanAccessFunc) (
const gpointer);
197typedef void (*BooleanSetterFunc) (
const gpointer, gboolean);
206 g_return_if_fail (pObject != NULL);
207 g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
209 auto val = row.get_int_at_col (m_col_name);
211 set_parameter(pObject,
static_cast<int>(*val),
212 reinterpret_cast<BooleanSetterFunc
>(get_setter(obj_name)),
220 vec.emplace_back(std::move(info));
225 const gpointer pObject,
226 PairVec& vec)
const noexcept
228 add_value_to_vec<int>(obj_name, pObject, vec);
232typedef gint64 (*Int64AccessFunc) (
const gpointer);
233typedef void (*Int64SetterFunc) (
const gpointer, gint64);
242 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
244 auto val = row.get_int_at_col (m_col_name);
246 set_parameter(pObject, *val,
247 reinterpret_cast<Int64SetterFunc
>(get_setter(obj_name)),
256 vec.emplace_back(std::move(info));
260GncSqlColumnTableEntry::get_row_value_from_object<int64_t>(
QofIdTypeConst obj_name,
261 const void* pObject)
const
263 g_return_val_if_fail(obj_name !=
nullptr && pObject !=
nullptr,
265 int64_t result = INT64_C(0);
266 if (m_gobj_param_name !=
nullptr)
267 g_object_get(
const_cast<void*
>(pObject), m_gobj_param_name,
271 auto getter = (Int64AccessFunc)
get_getter(obj_name);
272 if (getter !=
nullptr)
273 result = (getter)(
const_cast<void*
>(pObject));
280 const gpointer pObject,
281 PairVec& vec)
const noexcept
283 add_value_to_vec<int64_t>(obj_name, pObject, vec);
294 g_return_if_fail (pObject != NULL);
295 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
298 if (
auto int_val{row.get_int_at_col(m_col_name)})
299 val =
static_cast<decltype(val)
>(*int_val);
300 else if (
auto float_val{row.get_float_at_col(m_col_name)})
301 val =
static_cast<decltype(val)
>(*float_val);
302 else if (
auto double_val{row.get_double_at_col(m_col_name)})
305 set_parameter(pObject, val, get_setter(obj_name), m_gobj_param_name);
312 vec.emplace_back(std::move(info));
317 const gpointer pObject,
318 PairVec& vec)
const noexcept
320 add_value_to_vec<double*>(obj_name, pObject, vec);
335 g_return_if_fail (pObject != NULL);
336 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
338 auto strval{row.get_string_at_col(m_col_name)};
339 if (strval && string_to_guid (strval->c_str(), &guid))
340 set_parameter(pObject, &guid, get_setter(obj_name), m_gobj_param_name);
347 vec.emplace_back(std::move(info));
352 const gpointer pObject,
353 PairVec& vec)
const noexcept
355 auto s = get_row_value_from_object<GncGUID*>(obj_name, pObject);
360 vec.emplace_back (std::make_pair (std::string{m_col_name}, quote_string(guid_s)));
366typedef time64 (*Time64AccessFunc) (
const gpointer);
367typedef void (*Time64SetterFunc) (
const gpointer,
time64);
368constexpr int TIME_COL_SIZE = 4 + 3 + 3 + 3 + 3 + 3;
378 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
379 auto strval = row.get_string_at_col(m_col_name);
382 if (!strval->empty())
386 t =
static_cast<time64>(time);
388 catch (
const std::invalid_argument& err)
390 PWARN(
"An invalid date %s was found in your database."
391 "It has been set to 1 January 1970.",
397 if (
auto time64val = row.get_time64_at_col (m_col_name))
401 if (m_gobj_param_name !=
nullptr)
404 set_parameter(pObject, &t64, m_gobj_param_name);
408 set_parameter(pObject, t,
409 reinterpret_cast<Time64SetterFunc
>(get_setter(obj_name)),
419 vec.emplace_back(std::move(info));
424 const gpointer pObject,
425 PairVec& vec)
const noexcept
432 if (m_gobj_param_name !=
nullptr)
435 g_object_get (pObject, m_gobj_param_name, &t,
nullptr);
440 auto getter = (Time64AccessFunc)get_getter (obj_name);
441 g_return_if_fail(getter !=
nullptr);
442 t64 = (*getter)(pObject);
444 if (t64 > MINTIME && t64 < MAXTIME)
447 std::string timestr(
"'");
448 timestr += time.format_iso8601() +
"'";
449 vec.emplace_back (std::make_pair (std::string{m_col_name}, timestr));
453 vec.emplace_back (std::make_pair (std::string{m_col_name},
459#define DATE_COL_SIZE 8
465 gpointer pObject)
const noexcept
467 g_return_if_fail (pObject != NULL);
468 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
469 if (row.is_col_null(m_col_name))
472 g_date_clear (&date, 1);
474 auto strval{row.get_string_at_col(m_col_name)};
479 auto year =
static_cast<GDateYear
>(stoi (strval->substr (0,4)));
480 auto month =
static_cast<GDateMonth
>(stoi (strval->substr (4,2)));
481 auto day =
static_cast<GDateDay
>(stoi (strval->substr (6,2)));
483 if (year != 0 || month != 0 || day != (GDateDay)0)
484 g_date_set_dmy(&date, day, month, year);
488 auto timeval = row.get_time64_at_col(m_col_name);
494 auto time = *timeval;
496 g_date_set_dmy(&date, tm->tm_mday,
497 static_cast<GDateMonth
>(tm->tm_mon + 1),
502 set_parameter(pObject, &date, get_setter(obj_name), m_gobj_param_name);
509 vec.emplace_back(std::move(info));
514 const gpointer pObject,
515 PairVec& vec)
const noexcept
517 GDate *date = get_row_value_from_object<GDate*>(obj_name, pObject);
519 if (date && g_date_valid (date))
521 std::ostringstream buf;
522 buf << std::setfill (
'0') << std::setw (4) << g_date_get_year (date) <<
523 std::setw (2) << g_date_get_month (date) <<
524 std::setw (2) <<
static_cast<int>(g_date_get_day (date));
525 vec.emplace_back (std::make_pair (std::string{m_col_name},
526 quote_string(buf.str())));
532typedef gnc_numeric (*NumericGetterFunc) (
const gpointer);
533typedef void (*NumericSetterFunc) (gpointer, gnc_numeric);
535static const EntryVec numeric_col_table =
537 gnc_sql_make_table_entry<CT_INT64>(
"num", 0, COL_NNUL,
"guid"),
538 gnc_sql_make_table_entry<CT_INT64>(
"denom", 0, COL_NNUL,
"guid")
542void set_parameter<gpointer, gnc_numeric>(gpointer
object,
544 const char* property)
546 qof_instance_increase_editlevel(
object);
547 g_object_set(
object, property, &item,
nullptr);
548 qof_instance_decrease_editlevel(
object);
555 gpointer pObject)
const noexcept
559 g_return_if_fail (pObject != NULL);
560 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
562 auto buf = g_strdup_printf (
"%s_num", m_col_name);
563 auto num = row.get_int_at_col (buf);
565 buf = g_strdup_printf (
"%s_denom", m_col_name);
566 auto denom = row.get_int_at_col (buf);
571 auto n = gnc_numeric_create (*num, *denom);
572 set_parameter(pObject, n,
573 reinterpret_cast<NumericSetterFunc
>(get_setter(obj_name)),
582 for (
auto const& subtable_row : numeric_col_table)
584 gchar* buf = g_strdup_printf(
"%s_%s", m_col_name,
585 subtable_row->m_col_name);
587 m_flags & COL_PKEY, m_flags & COL_NNUL);
589 vec.emplace_back(std::move(info));
595 const gpointer pObject,
596 PairVec& vec)
const noexcept
599 NumericGetterFunc getter;
602 g_return_if_fail (obj_name != NULL);
603 g_return_if_fail (pObject != NULL);
605 if (m_gobj_param_name !=
nullptr)
608 g_object_get (pObject, m_gobj_param_name, &s, NULL);
613 getter =
reinterpret_cast<NumericGetterFunc
>(get_getter (obj_name));
616 n = (*getter) (pObject);
620 n = gnc_numeric_zero ();
624 std::ostringstream buf;
625 std::string num_col{m_col_name};
626 std::string denom_col{m_col_name};
628 denom_col +=
"_denom";
629 buf << gnc_numeric_num (n);
630 vec.emplace_back (std::make_pair (num_col, buf.str ()));
632 buf << gnc_numeric_denom (n);
633 vec.emplace_back (denom_col, buf.str ());
637_retrieve_guid_ (gpointer pObject, gpointer pValue)
642 g_return_if_fail (pObject != NULL);
643 g_return_if_fail (pValue != NULL);
649static EntryVec guid_table
651 gnc_sql_make_table_entry<CT_GUID>(
"guid", 0, 0,
nullptr, _retrieve_guid_)
659 g_return_val_if_fail (sql_be != NULL, NULL);
661 gnc_sql_load_object (sql_be, row, NULL, &guid, guid_table);
669 const EntryVec&
table)
671 g_return_if_fail (sql_be != NULL);
672 g_return_if_fail (pObject != NULL);
674 for (
auto const& table_row :
table)
676 table_row->load (sql_be, row, obj_name, pObject);
681gnc_sql_append_guids_to_sql (std::stringstream& sql,
682 const InstanceVec& instances)
686 for (
auto inst : instances)
690 if (inst != *(instances.begin()))
694 sql <<
"'" << guid_buf <<
"'";
697 return instances.size();
707GncSqlColumnTableEntry::get_row_value_from_object<int>(
QofIdTypeConst obj_name,
709 std::false_type)
const
711 g_return_val_if_fail(obj_name !=
nullptr && pObject !=
nullptr, 0);
713 if (m_gobj_param_name !=
nullptr)
714 g_object_get(
const_cast<void*
>(pObject), m_gobj_param_name, &result,
719 if (getter !=
nullptr)
721 auto value = ((getter)(
const_cast<void*
>(pObject),
nullptr));
722 result =
reinterpret_cast<uint64_t
>(value) &
723 UINT64_C(0x00000000FFFFFFFF);
Main SQL backend structure.
void add_to_query(QofIdTypeConst obj_name, void *pObject, PairVec &vec) const noexcept override
Add a pair of the table column heading and object's value's string representation to a PairVec; used ...
void add_to_table(ColVec &vec) const noexcept override
Add a GncSqlColumnInfo structure for the column type to a ColVec.
void load(const GncSqlBackend *sql_be, GncSqlRow &row, QofIdTypeConst obj_name, void *pObject) const noexcept override
Load a value into an object from the database row.
QofSetterFunc get_setter(QofIdTypeConst obj_name) const noexcept
Retrieve the setter function depending on whether it's an auto-increment field, a QofClass getter,...
void add_objectref_guid_to_query(QofIdTypeConst obj_name, const void *pObject, PairVec &vec) const noexcept
Adds a name/guid std::pair to a PairVec for creating a query.
void add_objectref_guid_to_table(ColVec &vec) const noexcept
Adds a column info structure for an object reference GncGUID to a ColVec.
QofAccessFunc get_getter(QofIdTypeConst obj_name) const noexcept
Retrieve the getter function depending on whether it's an auto-increment field, a QofClass getter,...
Row of SQL Query results.
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
QofSetterFunc qof_class_get_parameter_setter(QofIdTypeConst obj_name, const char *parameter)
Return the object's parameter setter function.
QofAccessFunc qof_class_get_parameter_getter(QofIdTypeConst obj_name, const char *parameter)
Return the object's parameter getter function.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
#define PWARN(format, args...)
Log a warning.
The type used to store guids in C.
information required to create a column in a table.