28 #include <gnc-datetime.hpp> 29 #include "gnc-sql-backend.hpp" 30 #include "gnc-sql-object-backend.hpp" 31 #include "gnc-sql-column-table-entry.hpp" 32 #include "gnc-sql-result.hpp" 38 get_autoinc_id (
void*
object,
const QofParam* param)
45 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));
261 const gpointer pObject,
262 PairVec& vec)
const noexcept
264 add_value_to_vec<int64_t>(obj_name, pObject, vec);
275 g_return_if_fail (pObject != NULL);
276 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
279 if (
auto int_val{row.get_int_at_col(m_col_name)})
280 val =
static_cast<decltype(val)
>(*int_val);
281 else if (
auto float_val{row.get_float_at_col(m_col_name)})
282 val =
static_cast<decltype(val)
>(*float_val);
283 else if (
auto double_val{row.get_double_at_col(m_col_name)})
286 set_parameter(pObject, val, get_setter(obj_name), m_gobj_param_name);
293 vec.emplace_back(std::move(info));
298 const gpointer pObject,
299 PairVec& vec)
const noexcept
301 add_value_to_vec<double*>(obj_name, pObject, vec);
316 g_return_if_fail (pObject != NULL);
317 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
319 auto strval{row.get_string_at_col(m_col_name)};
321 set_parameter(pObject, &guid, get_setter(obj_name), m_gobj_param_name);
328 vec.emplace_back(std::move(info));
333 const gpointer pObject,
334 PairVec& vec)
const noexcept
336 auto s = get_row_value_from_object<GncGUID*>(obj_name, pObject);
341 vec.emplace_back (std::make_pair (std::string{m_col_name}, quote_string(guid_s)));
347 typedef time64 (*Time64AccessFunc) (
const gpointer);
348 typedef void (*Time64SetterFunc) (
const gpointer,
time64);
349 constexpr
int TIME_COL_SIZE = 4 + 3 + 3 + 3 + 3 + 3;
359 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
360 auto strval = row.get_string_at_col(m_col_name);
363 if (!strval->empty())
367 t =
static_cast<time64>(time);
369 catch (
const std::invalid_argument& err)
371 PWARN(
"An invalid date %s was found in your database." 372 "It has been set to 1 January 1970.",
378 if (
auto time64val = row.get_time64_at_col (m_col_name))
382 if (m_gobj_param_name !=
nullptr)
385 set_parameter(pObject, &t64, m_gobj_param_name);
389 set_parameter(pObject, t,
390 reinterpret_cast<Time64SetterFunc>(get_setter(obj_name)),
400 vec.emplace_back(std::move(info));
405 const gpointer pObject,
406 PairVec& vec)
const noexcept
413 if (m_gobj_param_name !=
nullptr)
416 g_object_get (pObject, m_gobj_param_name, &t,
nullptr);
421 auto getter = (Time64AccessFunc)get_getter (obj_name);
422 g_return_if_fail(getter !=
nullptr);
423 t64 = (*getter)(pObject);
425 if (t64 > MINTIME && t64 < MAXTIME)
428 std::string timestr(
"'");
429 timestr += time.format_iso8601() +
"'";
430 vec.emplace_back (std::make_pair (std::string{m_col_name}, timestr));
434 vec.emplace_back (std::make_pair (std::string{m_col_name},
440 #define DATE_COL_SIZE 8 446 gpointer pObject)
const noexcept
448 g_return_if_fail (pObject != NULL);
449 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
450 if (row.is_col_null(m_col_name))
453 g_date_clear (&date, 1);
455 auto strval{row.get_string_at_col(m_col_name)};
460 auto year =
static_cast<GDateYear
>(stoi (strval->substr (0,4)));
461 auto month =
static_cast<GDateMonth
>(stoi (strval->substr (4,2)));
462 auto day =
static_cast<GDateDay
>(stoi (strval->substr (6,2)));
464 if (year != 0 || month != 0 || day != (GDateDay)0)
465 g_date_set_dmy(&date, day, month, year);
469 auto timeval = row.get_time64_at_col(m_col_name);
475 auto time = *timeval;
477 g_date_set_dmy(&date, tm->tm_mday,
478 static_cast<GDateMonth>(tm->tm_mon + 1),
483 set_parameter(pObject, &date, get_setter(obj_name), m_gobj_param_name);
490 vec.emplace_back(std::move(info));
495 const gpointer pObject,
496 PairVec& vec)
const noexcept
498 GDate *date = get_row_value_from_object<GDate*>(obj_name, pObject);
500 if (date && g_date_valid (date))
502 std::ostringstream buf;
503 buf << std::setfill (
'0') << std::setw (4) << g_date_get_year (date) <<
504 std::setw (2) << g_date_get_month (date) <<
505 std::setw (2) <<
static_cast<int>(g_date_get_day (date));
506 vec.emplace_back (std::make_pair (std::string{m_col_name},
507 quote_string(buf.str())));
513 typedef gnc_numeric (*NumericGetterFunc) (
const gpointer);
514 typedef void (*NumericSetterFunc) (gpointer, gnc_numeric);
516 static const EntryVec numeric_col_table =
518 gnc_sql_make_table_entry<CT_INT64>(
"num", 0, COL_NNUL,
"guid"),
519 gnc_sql_make_table_entry<CT_INT64>(
"denom", 0, COL_NNUL,
"guid")
523 void set_parameter<gpointer, gnc_numeric>(gpointer object,
525 const char* property)
527 qof_instance_increase_editlevel(
object);
528 g_object_set(
object, property, &item,
nullptr);
529 qof_instance_decrease_editlevel(
object);
536 gpointer pObject)
const noexcept
540 g_return_if_fail (pObject != NULL);
541 g_return_if_fail (m_gobj_param_name !=
nullptr || get_setter(obj_name) !=
nullptr);
543 auto buf = g_strdup_printf (
"%s_num", m_col_name);
544 auto num = row.get_int_at_col (buf);
546 buf = g_strdup_printf (
"%s_denom", m_col_name);
547 auto denom = row.get_int_at_col (buf);
552 auto n = gnc_numeric_create (*num, *denom);
553 set_parameter(pObject, n,
554 reinterpret_cast<NumericSetterFunc>(get_setter(obj_name)),
563 for (
auto const& subtable_row : numeric_col_table)
565 gchar* buf = g_strdup_printf(
"%s_%s", m_col_name,
566 subtable_row->m_col_name);
568 m_flags & COL_PKEY, m_flags & COL_NNUL);
570 vec.emplace_back(std::move(info));
576 const gpointer pObject,
577 PairVec& vec)
const noexcept
580 NumericGetterFunc getter;
583 g_return_if_fail (obj_name != NULL);
584 g_return_if_fail (pObject != NULL);
586 if (m_gobj_param_name !=
nullptr)
589 g_object_get (pObject, m_gobj_param_name, &s, NULL);
594 getter =
reinterpret_cast<NumericGetterFunc
>(get_getter (obj_name));
597 n = (*getter) (pObject);
601 n = gnc_numeric_zero ();
605 std::ostringstream buf;
606 std::string num_col{m_col_name};
607 std::string denom_col{m_col_name};
609 denom_col +=
"_denom";
610 buf << gnc_numeric_num (n);
611 vec.emplace_back (std::make_pair (num_col, buf.str ()));
613 buf << gnc_numeric_denom (n);
614 vec.emplace_back (denom_col, buf.str ());
618 _retrieve_guid_ (gpointer pObject, gpointer pValue)
623 g_return_if_fail (pObject != NULL);
624 g_return_if_fail (pValue != NULL);
630 static EntryVec guid_table
632 gnc_sql_make_table_entry<CT_GUID>(
"guid", 0, 0,
nullptr, _retrieve_guid_)
640 g_return_val_if_fail (sql_be != NULL, NULL);
642 gnc_sql_load_object (sql_be, row, NULL, &guid, guid_table);
650 const EntryVec&
table)
652 g_return_if_fail (sql_be != NULL);
653 g_return_if_fail (pObject != NULL);
655 for (
auto const& table_row :
table)
657 table_row->load (sql_be, row, obj_name, pObject);
662 gnc_sql_append_guids_to_sql (std::stringstream& sql,
663 const InstanceVec& instances)
667 for (
auto inst : instances)
671 if (inst != *(instances.begin()))
675 sql <<
"'" << guid_buf <<
"'";
678 return instances.size();
688 GncSqlColumnTableEntry::get_row_value_from_object<int>(
QofIdTypeConst obj_name,
690 std::false_type)
const 692 g_return_val_if_fail(obj_name !=
nullptr && pObject !=
nullptr, 0);
694 if (m_gobj_param_name !=
nullptr)
695 g_object_get(const_cast<void*>(pObject), m_gobj_param_name, &result,
700 if (getter !=
nullptr)
702 auto value = ((getter)(const_cast<void*>(pObject),
nullptr));
703 result =
reinterpret_cast<uint64_t
>(value) &
704 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...