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" 39 get_autoinc_id (
void*
object,
const QofParam* param)
46 set_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())));
160 typedef gint (*IntAccessFunc) (
const gpointer);
161 typedef 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);
196 typedef gboolean (*BooleanAccessFunc) (
const gpointer);
197 typedef 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);
232 typedef gint64 (*Int64AccessFunc) (
const gpointer);
233 typedef 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));
260 GncSqlColumnTableEntry::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)};
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)));
366 typedef time64 (*Time64AccessFunc) (
const gpointer);
367 typedef void (*Time64SetterFunc) (
const gpointer,
time64);
368 constexpr
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())));
532 typedef gnc_numeric (*NumericGetterFunc) (
const gpointer);
533 typedef void (*NumericSetterFunc) (gpointer, gnc_numeric);
535 static 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")
542 void 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);
649 static 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);
681 gnc_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();
707 GncSqlColumnTableEntry::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);
information required to create a column in a table.
QofSetterFunc get_setter(QofIdTypeConst obj_name) const noexcept
Retrieve the setter function depending on whether it's an auto-increment field, a QofClass getter...
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
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.
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
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 ...
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...
QofAccessFunc qof_class_get_parameter_getter(QofIdTypeConst obj_name, const char *parameter)
Return the object's parameter getter function.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
#define PWARN(format, args...)
Log a warning.
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.
Row of SQL Query results.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
void add_to_table(ColVec &vec) const noexcept override
Add a GncSqlColumnInfo structure for the column type to a ColVec.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void add_objectref_guid_to_table(ColVec &vec) const noexcept
Adds a column info structure for an object reference GncGUID to a ColVec.
QofSetterFunc qof_class_get_parameter_setter(QofIdTypeConst obj_name, const char *parameter)
Return the object's parameter setter function.
The type used to store guids in C.
Main SQL backend structure.
QofAccessFunc get_getter(QofIdTypeConst obj_name) const noexcept
Retrieve the getter function depending on whether it's an auto-increment field, a QofClass getter...