GnuCash  5.6-150-g038405b370+
gnc-sql-column-table-entry.cpp
1 /********************************************************************
2  * gnc-sql-column-table-entry.cpp: Implement GncSqlColumnTableEntry *
3  * *
4  * Copyright 2016 John Ralls <jralls@ceridwen.us> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22 \********************************************************************/
23 
24 #include <config.h>
25 #include <qof.h>
26 #include <sstream>
27 #include <iomanip>
28 #include <cstdint>
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"
34 
35 static QofLogModule log_module = G_LOG_DOMAIN;
36 
37 /* ================================================================= */
38 static gpointer
39 get_autoinc_id (void* object, const QofParam* param)
40 {
41  // Just need a 0 to force a new autoinc value
42  return (gpointer)0;
43 }
44 
45 static void
46 set_autoinc_id (void* object, void* item)
47 {
48  // Nowhere to put the ID
49 }
50 
53 {
54  QofAccessFunc getter;
55 
56  g_return_val_if_fail (obj_name != NULL, NULL);
57 
58  if (m_flags & COL_AUTOINC)
59  {
60  getter = get_autoinc_id;
61  }
62  else if (m_qof_param_name != NULL)
63  {
64  getter = qof_class_get_parameter_getter (obj_name, m_qof_param_name);
65  }
66  else
67  {
68  getter = m_getter;
69  }
70 
71  return getter;
72 }
73 
76 {
77  QofSetterFunc setter = nullptr;
78  if (m_flags & COL_AUTOINC)
79  {
80  setter = set_autoinc_id;
81  }
82  else if (m_qof_param_name != nullptr)
83  {
84  g_assert (obj_name != NULL);
85  setter = qof_class_get_parameter_setter (obj_name, m_qof_param_name);
86  }
87  else
88  {
89  setter = m_setter;
90  }
91  return setter;
92 }
93 
94 void
96  const void* pObject,
97  PairVec& vec) const noexcept
98 {
99  auto inst = get_row_value_from_object<QofInstance*>(obj_name, pObject);
100  if (inst == nullptr) return;
101  auto guid = qof_instance_get_guid (inst);
102  if (guid != nullptr) {
103  gchar *guid_s = guid_to_string(guid);
104  vec.emplace_back (std::make_pair (std::string{m_col_name}, quote_string(guid_s)));
105  g_free(guid_s);
106  }
107 }
108 
109 void
111 {
112  GncSqlColumnInfo info{*this, BCT_STRING, GUID_ENCODING_LENGTH, FALSE};
113  vec.emplace_back(std::move(info));
114 }
115 
116 
117 /* ----------------------------------------------------------------- */
118 template<> void
120  GncSqlRow& row,
121  QofIdTypeConst obj_name,
122  gpointer pObject) const noexcept
123 {
124  g_return_if_fail (pObject != NULL);
125  g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
126 
127  auto s = row.get_string_at_col (m_col_name);
128  if (s)
129  set_parameter(pObject, s->c_str(), get_setter(obj_name), m_gobj_param_name);
130 }
131 
132 template<> void
134 {
135  GncSqlColumnInfo info{*this, BCT_STRING, m_size, TRUE};
136  vec.emplace_back(std::move(info));
137 }
138 
139 /* char is unusual in that we get a pointer but don't deref it to pass
140  * it to operator<<().
141  */
142 template<> void
144  const gpointer pObject,
145  PairVec& vec) const noexcept
146 {
147  auto s = get_row_value_from_object<char*>(obj_name, pObject);
148 
149  if (s != nullptr)
150  {
151  std::ostringstream stream;
152  stream << s;
153  vec.emplace_back (std::make_pair (std::string{m_col_name},
154  quote_string(stream.str())));
155  return;
156  }
157 }
158 
159 /* ----------------------------------------------------------------- */
160 typedef gint (*IntAccessFunc) (const gpointer);
161 typedef void (*IntSetterFunc) (const gpointer, gint);
162 
163 template<> void
165  GncSqlRow& row,
166  QofIdTypeConst obj_name,
167  gpointer pObject) const noexcept
168 {
169 
170  g_return_if_fail (pObject != NULL);
171  g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
172 
173  auto val = row.get_int_at_col(m_col_name);
174  if (val)
175  set_parameter(pObject, *val,
176  reinterpret_cast<IntSetterFunc>(get_setter(obj_name)),
177  m_gobj_param_name);
178 }
179 
180 template<> void
182 {
183  GncSqlColumnInfo info{*this, BCT_INT, 0, FALSE};
184  vec.emplace_back(std::move(info));
185 }
186 
187 template<> void
189  const gpointer pObject,
190  PairVec& vec) const noexcept
191 {
192  add_value_to_vec<int>(obj_name, pObject, vec);
193 }
194 
195 /* ----------------------------------------------------------------- */
196 typedef gboolean (*BooleanAccessFunc) (const gpointer);
197 typedef void (*BooleanSetterFunc) (const gpointer, gboolean);
198 
199 template<> void
201  GncSqlRow& row,
202  QofIdTypeConst obj_name,
203  gpointer pObject)
204  const noexcept
205 {
206  g_return_if_fail (pObject != NULL);
207  g_return_if_fail (m_gobj_param_name != NULL || get_setter(obj_name) != NULL);
208 
209  auto val = row.get_int_at_col (m_col_name);
210  if (val)
211  set_parameter(pObject, static_cast<int>(*val),
212  reinterpret_cast<BooleanSetterFunc>(get_setter(obj_name)),
213  m_gobj_param_name);
214 }
215 
216 template<> void
218 {
219  GncSqlColumnInfo info{*this, BCT_INT, 0, FALSE};
220  vec.emplace_back(std::move(info));
221 }
222 
223 template<> void
225  const gpointer pObject,
226  PairVec& vec) const noexcept
227 {
228  add_value_to_vec<int>(obj_name, pObject, vec);
229 }
230 
231 /* ----------------------------------------------------------------- */
232 typedef gint64 (*Int64AccessFunc) (const gpointer);
233 typedef void (*Int64SetterFunc) (const gpointer, gint64);
234 
235 template<> void
237  GncSqlRow& row,
238  QofIdTypeConst obj_name,
239  gpointer pObject)
240  const noexcept
241 {
242  g_return_if_fail (m_gobj_param_name != nullptr || get_setter(obj_name) != nullptr);
243 
244  auto val = row.get_int_at_col (m_col_name);
245  if (val)
246  set_parameter(pObject, *val,
247  reinterpret_cast<Int64SetterFunc>(get_setter(obj_name)),
248  m_gobj_param_name);
249 }
250 
251 template<> void
253 {
254 
255  GncSqlColumnInfo info{*this, BCT_INT64, 0, FALSE};
256  vec.emplace_back(std::move(info));
257 }
258 
259 template<> gint64
260 GncSqlColumnTableEntry::get_row_value_from_object<int64_t>(QofIdTypeConst obj_name,
261  const void* pObject) const
262 {
263  g_return_val_if_fail(obj_name != nullptr && pObject != nullptr,
264  INT64_C(0));
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,
268  &result, nullptr);
269  else
270  {
271  auto getter = (Int64AccessFunc)get_getter(obj_name);
272  if (getter != nullptr)
273  result = (getter)(const_cast<void*>(pObject));
274  }
275  return result;
276 }
277 
278 template<> void
280  const gpointer pObject,
281  PairVec& vec) const noexcept
282 {
283  add_value_to_vec<int64_t>(obj_name, pObject, vec);
284 }
285 /* ----------------------------------------------------------------- */
286 
287 template<> void
289  GncSqlRow& row,
290  QofIdTypeConst obj_name,
291  gpointer pObject)
292  const noexcept
293 {
294  g_return_if_fail (pObject != NULL);
295  g_return_if_fail (m_gobj_param_name != nullptr || get_setter(obj_name) != nullptr);
296  double val{0.0};
297 
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)})
303  val = *double_val;
304 
305  set_parameter(pObject, val, get_setter(obj_name), m_gobj_param_name);
306 }
307 
308 template<> void
310 {
311  GncSqlColumnInfo info{*this, BCT_DOUBLE, 0, FALSE};
312  vec.emplace_back(std::move(info));
313 }
314 
315 template<> void
317  const gpointer pObject,
318  PairVec& vec) const noexcept
319 {
320  add_value_to_vec<double*>(obj_name, pObject, vec);
321 }
322 
323 /* ----------------------------------------------------------------- */
324 
325 template<> void
327  GncSqlRow& row,
328  QofIdTypeConst obj_name,
329  gpointer pObject)
330  const noexcept
331 {
332 
333  GncGUID guid;
334 
335  g_return_if_fail (pObject != NULL);
336  g_return_if_fail (m_gobj_param_name != nullptr || get_setter(obj_name) != nullptr);
337 
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);
341 }
342 
343 template<> void
345 {
346  GncSqlColumnInfo info{*this, BCT_STRING, GUID_ENCODING_LENGTH, FALSE};
347  vec.emplace_back(std::move(info));
348 }
349 
350 template<> void
352  const gpointer pObject,
353  PairVec& vec) const noexcept
354 {
355  auto s = get_row_value_from_object<GncGUID*>(obj_name, pObject);
356 
357  if (s != nullptr)
358  {
359  gchar *guid_s = guid_to_string(s);
360  vec.emplace_back (std::make_pair (std::string{m_col_name}, quote_string(guid_s)));
361  g_free(guid_s);
362  return;
363  }
364 }
365 /* ----------------------------------------------------------------- */
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;
369 
370 template<> void
372  GncSqlRow& row,
373  QofIdTypeConst obj_name,
374  gpointer pObject)
375  const noexcept
376 {
377  time64 t{0};
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);
380  if (strval)
381  {
382  if (!strval->empty())
383  try
384  {
385  GncDateTime time(*strval);
386  t = static_cast<time64>(time);
387  }
388  catch (const std::invalid_argument& err)
389  {
390  PWARN("An invalid date %s was found in your database."
391  "It has been set to 1 January 1970.",
392  strval->c_str());
393  }
394  }
395  else
396  {
397  if (auto time64val = row.get_time64_at_col (m_col_name))
398  t = *time64val;
399  }
400 
401  if (m_gobj_param_name != nullptr)
402  {
403  Time64 t64{t};
404  set_parameter(pObject, &t64, m_gobj_param_name);
405  }
406  else
407  {
408  set_parameter(pObject, t,
409  reinterpret_cast<Time64SetterFunc>(get_setter(obj_name)),
410  nullptr);
411  }
412 }
413 
414 template<> void
416 {
417 
418  GncSqlColumnInfo info{*this, BCT_DATETIME, TIME_COL_SIZE, FALSE};
419  vec.emplace_back(std::move(info));
420 }
421 
422 template<> void
424  const gpointer pObject,
425  PairVec& vec) const noexcept
426 {
427  /* We still can't use get_row_value_from_object because while g_value could
428  * contentedly store a time64 in an int64, KVP wouldn't be able to tell them
429  * apart, so we have the struct Time64 hack, see engine/gnc-date.c.
430  */
431  time64 t64;
432  if (m_gobj_param_name != nullptr)
433  {
434  Time64* t;
435  g_object_get (pObject, m_gobj_param_name, &t, nullptr);
436  t64 = t->t;
437  }
438  else
439  {
440  auto getter = (Time64AccessFunc)get_getter (obj_name);
441  g_return_if_fail(getter != nullptr);
442  t64 = (*getter)(pObject);
443  }
444  if (t64 > MINTIME && t64 < MAXTIME)
445  {
446  GncDateTime time(t64);
447  std::string timestr("'");
448  timestr += time.format_iso8601() + "'";
449  vec.emplace_back (std::make_pair (std::string{m_col_name}, timestr));
450  }
451  else
452  {
453  vec.emplace_back (std::make_pair (std::string{m_col_name},
454  "NULL"));
455  }
456 }
457 
458 /* ----------------------------------------------------------------- */
459 #define DATE_COL_SIZE 8
460 
461 template<> void
463  GncSqlRow& row,
464  QofIdTypeConst obj_name,
465  gpointer pObject) const noexcept
466 {
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))
470  return;
471  GDate date;
472  g_date_clear (&date, 1);
473 
474  auto strval{row.get_string_at_col(m_col_name)};
475  if (strval)
476  {
477  if (strval->empty())
478  return;
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)));
482 
483  if (year != 0 || month != 0 || day != (GDateDay)0)
484  g_date_set_dmy(&date, day, month, year);
485  }
486  else
487  {
488  auto timeval = row.get_time64_at_col(m_col_name);
489  if (!timeval)
490  return;
491  /* time64_to_gdate applies the tz, and gdates are saved
492  * as ymd, so we don't want that.
493  */
494  auto time = *timeval;
495  auto tm = gnc_gmtime(&time);
496  g_date_set_dmy(&date, tm->tm_mday,
497  static_cast<GDateMonth>(tm->tm_mon + 1),
498  tm->tm_year + 1900);
499  free(tm);
500  }
501 
502  set_parameter(pObject, &date, get_setter(obj_name), m_gobj_param_name);
503 }
504 
505 template<> void
507 {
508  GncSqlColumnInfo info{*this, BCT_DATE, DATE_COL_SIZE, FALSE};
509  vec.emplace_back(std::move(info));
510 }
511 
512 template<> void
514  const gpointer pObject,
515  PairVec& vec) const noexcept
516 {
517  GDate *date = get_row_value_from_object<GDate*>(obj_name, pObject);
518 
519  if (date && g_date_valid (date))
520  {
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())));
527  return;
528  }
529 }
530 
531 /* ----------------------------------------------------------------- */
532 typedef gnc_numeric (*NumericGetterFunc) (const gpointer);
533 typedef void (*NumericSetterFunc) (gpointer, gnc_numeric);
534 
535 static const EntryVec numeric_col_table =
536 {
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")
539 };
540 
541 template <>
542 void set_parameter<gpointer, gnc_numeric>(gpointer object,
543  gnc_numeric item,
544  const char* property)
545 {
546  qof_instance_increase_editlevel(object);
547  g_object_set(object, property, &item, nullptr);
548  qof_instance_decrease_editlevel(object);
549 };
550 
551 template<> void
553  GncSqlRow& row,
554  QofIdTypeConst obj_name,
555  gpointer pObject) const noexcept
556 {
557 
558 
559  g_return_if_fail (pObject != NULL);
560  g_return_if_fail (m_gobj_param_name != nullptr || get_setter(obj_name) != nullptr);
561 
562  auto buf = g_strdup_printf ("%s_num", m_col_name);
563  auto num = row.get_int_at_col (buf);
564  g_free (buf);
565  buf = g_strdup_printf ("%s_denom", m_col_name);
566  auto denom = row.get_int_at_col (buf);
567  g_free (buf);
568 
569  if (num && denom)
570  {
571  auto n = gnc_numeric_create (*num, *denom);
572  set_parameter(pObject, n,
573  reinterpret_cast<NumericSetterFunc>(get_setter(obj_name)),
574  m_gobj_param_name);
575  }
576 }
577 
578 template<> void
580 {
581 
582  for (auto const& subtable_row : numeric_col_table)
583  {
584  gchar* buf = g_strdup_printf("%s_%s", m_col_name,
585  subtable_row->m_col_name);
586  GncSqlColumnInfo info(buf, BCT_INT64, 0, false, false,
587  m_flags & COL_PKEY, m_flags & COL_NNUL);
588  g_free (buf);
589  vec.emplace_back(std::move(info));
590  }
591 }
592 
593 template<> void
595  const gpointer pObject,
596  PairVec& vec) const noexcept
597 {
598 /* We can't use get_row_value_from_object for the same reason as time64. */
599  NumericGetterFunc getter;
600  gnc_numeric n;
601 
602  g_return_if_fail (obj_name != NULL);
603  g_return_if_fail (pObject != NULL);
604 
605  if (m_gobj_param_name != nullptr)
606  {
607  gnc_numeric* s;
608  g_object_get (pObject, m_gobj_param_name, &s, NULL);
609  n = *s;
610  }
611  else
612  {
613  getter = reinterpret_cast<NumericGetterFunc>(get_getter (obj_name));
614  if (getter != NULL)
615  {
616  n = (*getter) (pObject);
617  }
618  else
619  {
620  n = gnc_numeric_zero ();
621  }
622  }
623 
624  std::ostringstream buf;
625  std::string num_col{m_col_name};
626  std::string denom_col{m_col_name};
627  num_col += "_num";
628  denom_col += "_denom";
629  buf << gnc_numeric_num (n);
630  vec.emplace_back (std::make_pair (num_col, buf.str ()));
631  buf.str ("");
632  buf << gnc_numeric_denom (n);
633  vec.emplace_back (denom_col, buf.str ());
634 }
635 
636 static void
637 _retrieve_guid_ (gpointer pObject, gpointer pValue)
638 {
639  GncGUID* pGuid = (GncGUID*)pObject;
640  GncGUID* guid = (GncGUID*)pValue;
641 
642  g_return_if_fail (pObject != NULL);
643  g_return_if_fail (pValue != NULL);
644 
645  *pGuid = *guid;
646 }
647 
648 // Table to retrieve just the guid
649 static EntryVec guid_table
650 {
651  gnc_sql_make_table_entry<CT_GUID>("guid", 0, 0, nullptr, _retrieve_guid_)
652 };
653 
654 const GncGUID*
655 gnc_sql_load_guid (const GncSqlBackend* sql_be, GncSqlRow& row)
656 {
657  static GncGUID guid;
658 
659  g_return_val_if_fail (sql_be != NULL, NULL);
660 
661  gnc_sql_load_object (sql_be, row, NULL, &guid, guid_table);
662 
663  return &guid;
664 }
665 
666 void
667 gnc_sql_load_object (const GncSqlBackend* sql_be, GncSqlRow& row,
668  QofIdTypeConst obj_name, gpointer pObject,
669  const EntryVec& table)
670 {
671  g_return_if_fail (sql_be != NULL);
672  g_return_if_fail (pObject != NULL);
673 
674  for (auto const& table_row : table)
675  {
676  table_row->load (sql_be, row, obj_name, pObject);
677  }
678 }
679 
680 uint_t
681 gnc_sql_append_guids_to_sql (std::stringstream& sql,
682  const InstanceVec& instances)
683 {
684  char guid_buf[GUID_ENCODING_LENGTH + 1];
685 
686  for (auto inst : instances)
687  {
688  (void)guid_to_string_buff (qof_instance_get_guid (inst), guid_buf);
689 
690  if (inst != *(instances.begin()))
691  {
692  sql << ",";
693  }
694  sql << "'" << guid_buf << "'";
695  }
696 
697  return instances.size();
698 }
699 
700 /* This is necessary for 64-bit builds because g++ complains
701  * that reinterpret_casting a void* (64 bits) to an int (32 bits)
702  * loses precision, so we have to explicitly dispose of the precision.
703  * FIXME: We shouldn't be storing ints in ptrs in the first place.
704  */
705 #ifdef __LP64__
706 template <> int
707 GncSqlColumnTableEntry::get_row_value_from_object<int>(QofIdTypeConst obj_name,
708  const void* pObject,
709  std::false_type) const
710 {
711  g_return_val_if_fail(obj_name != nullptr && pObject != nullptr, 0);
712  int result = 0;
713  if (m_gobj_param_name != nullptr)
714  g_object_get(const_cast<void*>(pObject), m_gobj_param_name, &result,
715  nullptr);
716  else
717  {
718  QofAccessFunc getter = get_getter(obj_name);
719  if (getter != nullptr)
720  {
721  auto value = ((getter)(const_cast<void*>(pObject), nullptr));
722  result = reinterpret_cast<uint64_t>(value) &
723  UINT64_C(0x00000000FFFFFFFF);
724  }
725  }
726  return result;
727 }
728 #endif
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&#39;s an auto-increment field, a QofClass getter...
GnuCash DateTime class.
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.
Definition: qofid.h:82
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&#39;s value&#39;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...
Definition: guid.cpp:173
QofAccessFunc qof_class_get_parameter_getter(QofIdTypeConst obj_name, const char *parameter)
Return the object&#39;s parameter getter function.
Definition: qofclass.cpp:156
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
Definition: qofclass.h:185
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
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.
Definition: guid.h:84
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition: qofclass.h:178
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
Definition: guid.cpp:164
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
Definition: gnc-date.cpp:176
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...
Definition: gnc-date.h:87
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&#39;s parameter setter function.
Definition: qofclass.cpp:172
The type used to store guids in C.
Definition: guid.h:75
Main SQL backend structure.
QofAccessFunc get_getter(QofIdTypeConst obj_name) const noexcept
Retrieve the getter function depending on whether it&#39;s an auto-increment field, a QofClass getter...