GnuCash  5.6-150-g038405b370+
Data Structures | Public Member Functions | Protected Attributes
GncSqlBackend Class Reference

Main SQL backend structure. More...

#include <gnc-sql-backend.hpp>

Inheritance diagram for GncSqlBackend:
QofBackend GncDbiBackend< Type >

Public Member Functions

 GncSqlBackend (GncSqlConnection *conn, QofBook *book)
 
void load (QofBook *, QofBackendLoadType) override
 Load the contents of an SQL database into a book. More...
 
void sync (QofBook *) override
 Save the contents of a book to an SQL database. More...
 
void begin (QofInstance *) override
 An object is about to be edited. More...
 
void commit (QofInstance *) override
 Object editing is complete and the object should be saved. More...
 
void rollback (QofInstance *) override
 Object editing has been cancelled. More...
 
void connect (GncSqlConnection *conn) noexcept
 Connect the backend to a GncSqlConnection. More...
 
void init_version_info () noexcept
 Initializes DB table version information. More...
 
bool reset_version_info () noexcept
 Resets the version table information by removing all version table info. More...
 
void finalize_version_info () noexcept
 Finalizes DB table version information. More...
 
GncSqlStatementPtr create_statement_from_sql (const std::string &str) const noexcept
 
GncSqlResultPtr execute_select_statement (const GncSqlStatementPtr &stmt) const noexcept
 Executes an SQL SELECT statement and returns the result rows. More...
 
int execute_nonselect_statement (const GncSqlStatementPtr &stmt) const noexcept
 
std::string quote_string (const std::string &) const noexcept
 
bool create_table (const std::string &table_name, const EntryVec &col_table) const noexcept
 Creates a table in the database. More...
 
bool create_table (const std::string &table_name, int table_version, const EntryVec &col_table) noexcept
 Creates a table in the database and sets its version. More...
 
void create_tables () noexcept
 Create/update all tables in the database.
 
bool create_index (const std::string &index_name, const std::string &table_name, const EntryVec &col_table) const noexcept
 Creates an index in the database. More...
 
bool add_columns_to_table (const std::string &table_name, const EntryVec &col_table) const noexcept
 Adds one or more columns to an existing table. More...
 
void upgrade_table (const std::string &table_name, const EntryVec &col_table) noexcept
 Upgrades a table to a new structure. More...
 
uint_t get_table_version (const std::string &table_name) const noexcept
 Returns the version number for a DB table. More...
 
bool set_table_version (const std::string &table_name, uint_t version) noexcept
 Registers the version for a table. More...
 
void commodity_for_postload_processing (gnc_commodity *)
 Register a commodity to be committed after loading is complete. More...
 
GncSqlObjectBackendPtr get_object_backend (const std::string &type) const noexcept
 Get the GncSqlObjectBackend for the indicated type. More...
 
bool object_in_db (const char *table_name, QofIdTypeConst obj_name, const gpointer pObject, const EntryVec &table) const noexcept
 Checks whether an object is in the database or not. More...
 
bool do_db_operation (E_DB_OPERATION op, const char *table_name, QofIdTypeConst obj_name, gpointer pObject, const EntryVec &table) const noexcept
 Performs an operation on the database. More...
 
bool save_commodity (gnc_commodity *comm) noexcept
 Ensure that a commodity referenced in another object is in fact saved in the database. More...
 
QofBook * book () const noexcept
 
void set_loading (bool loading) noexcept
 
bool pristine () const noexcept
 
void update_progress (double pct) const noexcept
 
void finish_progress () const noexcept
 
- Public Member Functions inherited from QofBackend
 QofBackend (const QofBackend &)=delete
 
 QofBackend (const QofBackend &&)=delete
 
virtual void session_begin (QofSession *session, const char *new_uri, SessionOpenMode mode)=0
 Open the file or connect to the server. More...
 
virtual void session_end ()=0
 
virtual void safe_sync (QofBook *)=0
 Perform a sync in a way that prevents data loss on a DBI backend.
 
virtual void export_coa (QofBook *)
 Extract the chart of accounts from the current database and create a new database with it. More...
 
void set_error (QofBackendError err)
 Set the error value only if there isn't already an error already.
 
QofBackendError get_error ()
 Retrieve the currently-stored error and clear it.
 
bool check_error ()
 Report if there is an error.
 
void set_message (std::string &&)
 Set a descriptive message that can be displayed to the user when there's an error.
 
const std::string && get_message ()
 Retrieve and clear the stored error message.
 
void set_percentage (QofBePercentageFunc pctfn)
 Store and retrieve a backend-specific function for determining the progress in completing a long operation, for use with a progress meter.
 
QofBePercentageFunc get_percentage ()
 
const std::string & get_uri ()
 Retrieve the backend's storage URI.
 

Protected Attributes

GncSqlConnectionm_conn = nullptr
 SQL connection.
 
QofBook * m_book = nullptr
 The primary, main open book.
 
bool m_loading
 We are performing an initial load.
 
bool m_in_query
 We are processing a query.
 
bool m_is_pristine_db
 Are we saving to a new pristine db?
 
const char * m_time_format = nullptr
 Server-specific date-time string format.
 
VersionVec m_versions
 Version number for each table.
 
- Protected Attributes inherited from QofBackend
QofBePercentageFunc m_percentage
 
std::string m_fullpath
 Each backend resolves a fully-qualified file path. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from QofBackend
static bool register_backend (const char *, const char *)
 Class methods for dynamically loading the several backends and for freeing them at shutdown.
 
static void release_backends ()
 

Detailed Description

Main SQL backend structure.

Definition at line 63 of file gnc-sql-backend.hpp.

Member Function Documentation

◆ add_columns_to_table()

bool GncSqlBackend::add_columns_to_table ( const std::string &  table_name,
const EntryVec &  col_table 
) const
noexcept

Adds one or more columns to an existing table.

Parameters
table_nameSQL table name
new_col_tableColumn table for new columns
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 182 of file gnc-sql-backend.cpp.

184 {
185  g_return_val_if_fail (m_conn != nullptr, false);
186 
187  ColVec info_vec;
188 
189  for (auto const& table_row : col_table)
190  {
191  table_row->add_to_table (info_vec);
192  }
193  return m_conn->add_columns_to_table(table_name, info_vec);
194 }
GncSqlConnection * m_conn
SQL connection.
virtual bool add_columns_to_table(const std::string &, const ColVec &) const noexcept=0
Returns TRUE if successful, FALSE if error.

◆ begin()

void GncSqlBackend::begin ( QofInstance inst)
overridevirtual

An object is about to be edited.

Parameters
instObject being edited

Reimplemented from QofBackend.

Definition at line 543 of file gnc-sql-backend.cpp.

544 {
545  //g_return_if_fail (inst != NULL);
546 
547  //ENTER (" ");
548  //LEAVE ("");
549 }

◆ commit()

void GncSqlBackend::commit ( QofInstance inst)
overridevirtual

Object editing is complete and the object should be saved.

Parameters
instObject being edited

Reimplemented from QofBackend.

Definition at line 577 of file gnc-sql-backend.cpp.

578 {
579  gboolean is_dirty;
580  gboolean is_destroying;
581  gboolean is_infant;
582 
583  g_return_if_fail (inst != NULL);
584  g_return_if_fail (m_conn != nullptr);
585 
587  {
589  (void)m_conn->rollback_transaction ();
590  return;
591  }
592  /* During initial load where objects are being created, don't commit
593  anything, but do mark the object as clean. */
594  if (m_loading)
595  {
596  qof_instance_mark_clean (inst);
597  return;
598  }
599 
600  // The engine has a PriceDB object but it isn't in the database
601  if (strcmp (inst->e_type, "PriceDB") == 0)
602  {
603  qof_instance_mark_clean (inst);
605  return;
606  }
607 
608  ENTER (" ");
609 
610  is_dirty = qof_instance_get_dirty_flag (inst);
611  is_destroying = qof_instance_get_destroying (inst);
612  is_infant = qof_instance_get_infant (inst);
613 
614  DEBUG ("%s dirty = %d, do_free = %d, infant = %d\n",
615  (inst->e_type ? inst->e_type : "(null)"),
616  is_dirty, is_destroying, is_infant);
617 
618  if (!is_dirty && !is_destroying)
619  {
620  LEAVE ("!dirty OR !destroying");
621  return;
622  }
623 
624  if (!m_conn->begin_transaction ())
625  {
626  PERR ("begin_transaction failed\n");
627  LEAVE ("Rolled back - database transaction begin error");
628  return;
629  }
630 
631  bool is_ok = true;
632 
633  auto obe = m_backend_registry.get_object_backend(std::string{inst->e_type});
634  if (obe != nullptr)
635  is_ok = obe->commit(this, inst);
636  else
637  {
638  PERR ("Unknown object type '%s'\n", inst->e_type);
639  (void)m_conn->rollback_transaction ();
640 
641  // Don't let unknown items still mark the book as being dirty
643  qof_instance_mark_clean (inst);
644  LEAVE ("Rolled back - unknown object type");
645  return;
646  }
647  if (!is_ok)
648  {
649  // Error - roll it back
650  (void)m_conn->rollback_transaction();
651 
652  // This *should* leave things marked dirty
653  LEAVE ("Rolled back - database error");
654  return;
655  }
656 
657  (void)m_conn->commit_transaction ();
658 
660  qof_instance_mark_clean (inst);
661 
662  LEAVE ("");
663 }
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
bool m_loading
We are performing an initial load.
GncSqlConnection * m_conn
SQL connection.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
Definition: qofbook.cpp:383
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object has been modified.
QofBook * m_book
The primary, main open book.
virtual bool commit_transaction() noexcept=0
Returns TRUE if successful, FALSE if error.
QofIdType e_type
Entity type.
Definition: qofinstance.h:75
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
Definition: qofbook.cpp:497
cannot write to file/directory
Definition: qofbackend.h:68
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
virtual bool begin_transaction() noexcept=0
Returns TRUE if successful, false if error.
virtual bool rollback_transaction() noexcept=0
Returns TRUE if successful, FALSE if error.
void set_error(QofBackendError err)
Set the error value only if there isn&#39;t already an error already.
Definition: qof-backend.cpp:56

◆ commodity_for_postload_processing()

void GncSqlBackend::commodity_for_postload_processing ( gnc_commodity *  commodity)

Register a commodity to be committed after loading is complete.

Necessary to save corrections made while loading.

Parameters
commThe commodity item to be committed.

Definition at line 561 of file gnc-sql-backend.cpp.

562 {
563  m_postload_commodities.push_back(commodity);
564 }

◆ connect()

void GncSqlBackend::connect ( GncSqlConnection conn)
noexcept

Connect the backend to a GncSqlConnection.

Sets up version info. Calling with nullptr clears the connection and destroys the version info.

Definition at line 94 of file gnc-sql-backend.cpp.

95 {
96  if (m_conn != nullptr && m_conn != conn)
97  delete m_conn;
99  m_conn = conn;
100 }
GncSqlConnection * m_conn
SQL connection.
void finalize_version_info() noexcept
Finalizes DB table version information.

◆ create_index()

bool GncSqlBackend::create_index ( const std::string &  index_name,
const std::string &  table_name,
const EntryVec &  col_table 
) const
noexcept

Creates an index in the database.

Parameters
index_nameIndex name
table_nameTable name
col_tableColumns that the index should index
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 173 of file gnc-sql-backend.cpp.

176 {
177  g_return_val_if_fail (m_conn != nullptr, false);
178  return m_conn->create_index(index_name, table_name, col_table);
179 }
GncSqlConnection * m_conn
SQL connection.
virtual bool create_index(const std::string &, const std::string &, const EntryVec &) const noexcept=0
Returns TRUE if successful, FALSE if error.

◆ create_table() [1/2]

bool GncSqlBackend::create_table ( const std::string &  table_name,
const EntryVec &  col_table 
) const
noexcept

Creates a table in the database.

Parameters
table_nameTable name
col_tableDB table description
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 148 of file gnc-sql-backend.cpp.

150 {
151  g_return_val_if_fail (m_conn != nullptr, false);
152 
153  ColVec info_vec;
154 
155  for (auto const& table_row : col_table)
156  {
157  table_row->add_to_table (info_vec);
158  }
159  return m_conn->create_table (table_name, info_vec);
160 
161 }
GncSqlConnection * m_conn
SQL connection.
virtual bool create_table(const std::string &, const ColVec &) const noexcept=0
Returns TRUE if successful, FALSE if error.

◆ create_table() [2/2]

bool GncSqlBackend::create_table ( const std::string &  table_name,
int  table_version,
const EntryVec &  col_table 
)
noexcept

Creates a table in the database and sets its version.

Parameters
table_nameTable name
table_versionTable version
col_tableDB table description
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 164 of file gnc-sql-backend.cpp.

166 {
167  if (create_table (table_name, col_table))
168  return set_table_version (table_name, table_version);
169  return false;
170 }
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.

◆ do_db_operation()

bool GncSqlBackend::do_db_operation ( E_DB_OPERATION  op,
const char *  table_name,
QofIdTypeConst  obj_name,
gpointer  pObject,
const EntryVec &  table 
) const
noexcept

Performs an operation on the database.

Parameters
opOperation type
table_nameSQL table name
obj_nameQOF object type name
pObjectGnucash object
tableDB table description
Returns
TRUE if successful, FALSE if not

Definition at line 854 of file gnc-sql-backend.cpp.

857 {
858  GncSqlStatementPtr stmt;
859 
860  g_return_val_if_fail (table_name != nullptr, false);
861  g_return_val_if_fail (obj_name != nullptr, false);
862  g_return_val_if_fail (pObject != nullptr, false);
863 
864  switch(op)
865  {
866  case OP_DB_INSERT:
867  stmt = build_insert_statement (table_name, obj_name, pObject, table);
868  break;
869  case OP_DB_UPDATE:
870  stmt = build_update_statement (table_name, obj_name, pObject, table);
871  break;
872  case OP_DB_DELETE:
873  stmt = build_delete_statement (table_name, obj_name, pObject, table);
874  break;
875  }
876  if (stmt == nullptr)
877  return false;
878  return (execute_nonselect_statement(stmt) != -1);
879 }

◆ execute_select_statement()

GncSqlResultPtr GncSqlBackend::execute_select_statement ( const GncSqlStatementPtr &  stmt) const
noexcept

Executes an SQL SELECT statement and returns the result rows.

If an error occurs, an entry is added to the log, an error status is returned to qof and nullptr is returned.

Parameters
statementStatement
Returns
Results, or nullptr if an error has occurred

Definition at line 115 of file gnc-sql-backend.cpp.

116 {
117  auto result = m_conn ? m_conn->execute_select_statement(stmt) : nullptr;
118  if (result == nullptr)
119  {
120  PERR ("SQL error: %s\n", stmt->to_sql());
122  }
123  return result;
124 }
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
GncSqlConnection * m_conn
SQL connection.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
error in response from server
Definition: qofbackend.h:71

◆ finalize_version_info()

void GncSqlBackend::finalize_version_info ( )
noexcept

Finalizes DB table version information.

Finalizes the version table info by destroying the hash table.

Parameters
beBackend struct

Definition at line 721 of file gnc-sql-backend.cpp.

722 {
723  m_versions.clear();
724 }
VersionVec m_versions
Version number for each table.

◆ get_object_backend()

GncSqlObjectBackendPtr GncSqlBackend::get_object_backend ( const std::string &  type) const
noexcept

Get the GncSqlObjectBackend for the indicated type.

Required because we need to pass a pointer to this to a callback via a C function.

Parameters
typeThe QofInstance type constant to select the object backend.

Definition at line 567 of file gnc-sql-backend.cpp.

568 {
569  return m_backend_registry.get_object_backend(type);
570 }

◆ get_table_version()

unsigned int GncSqlBackend::get_table_version ( const std::string &  table_name) const
noexcept

Returns the version number for a DB table.

Parameters
table_nameTable name
Returns
Version number, or 0 if the table does not exist

Definition at line 727 of file gnc-sql-backend.cpp.

728 {
729  /* If the db is pristine because it's being saved, the table does not exist. */
730  if (m_is_pristine_db)
731  return 0;
732 
733  auto version = std::find_if(m_versions.begin(), m_versions.end(),
734  [table_name](const VersionPair& version) {
735  return version.first == table_name; });
736  if (version != m_versions.end())
737  return version->second;
738  return 0;
739 }
VersionVec m_versions
Version number for each table.
bool m_is_pristine_db
Are we saving to a new pristine db?

◆ init_version_info()

void GncSqlBackend::init_version_info ( )
noexcept

Initializes DB table version information.

Sees if the version table exists, and if it does, loads the info into the version hash table.

Otherwise, it creates an empty version table.

Parameters
beBackend struct

Definition at line 673 of file gnc-sql-backend.cpp.

674 {
675  g_return_if_fail (m_conn != nullptr);
676  if (m_conn->does_table_exist (VERSION_TABLE_NAME))
677  {
678  std::string sql {"SELECT * FROM "};
679  sql += VERSION_TABLE_NAME;
680  auto stmt = m_conn->create_statement_from_sql(sql);
681  auto result = m_conn->execute_select_statement (stmt);
682  for (const auto& row : *result)
683  {
684  auto name = row.get_string_at_col (TABLE_COL_NAME);
685  auto version = row.get_int_at_col (VERSION_COL_NAME);
686  if (name && version)
687  m_versions.push_back(std::make_pair(*name, static_cast<unsigned int>(*version)));
688  }
689  }
690  else
691  {
692  create_table (VERSION_TABLE_NAME, version_table);
693  set_table_version("Gnucash", gnc_prefs_get_long_version ());
694  set_table_version("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
695  }
696 }
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.
VersionVec m_versions
Version number for each table.
GncSqlConnection * m_conn
SQL connection.
virtual bool does_table_exist(const std::string &) const noexcept=0
Returns true if successful.

◆ load()

void GncSqlBackend::load ( QofBook *  book,
QofBackendLoadType  loadType 
)
overridevirtual

Load the contents of an SQL database into a book.

Parameters
bookBook to be loaded

Implements QofBackend.

Definition at line 283 of file gnc-sql-backend.cpp.

284 {
285  Account* root;
286 
287  g_return_if_fail (book != NULL);
288 
289  ENTER ("sql_be=%p, book=%p", this, book);
290 
291  m_loading = TRUE;
292 
293  if (loadType == LOAD_TYPE_INITIAL_LOAD)
294  {
295  assert (m_book == nullptr);
296  m_book = book;
297 
298  auto num_types = m_backend_registry.size();
299  auto num_done = 0;
300 
301  /* Load any initial stuff. Some of this needs to happen in a certain order */
302  for (const auto& type : fixed_load_order)
303  {
304  num_done++;
305  auto obe = m_backend_registry.get_object_backend(type);
306  if (obe)
307  {
308  update_progress(num_done * 100 / num_types);
309  obe->load_all(this);
310  }
311  }
312  for (const auto& type : business_fixed_load_order)
313  {
314  num_done++;
315  auto obe = m_backend_registry.get_object_backend(type);
316  if (obe)
317  {
318  update_progress(num_done * 100 / num_types);
319  obe->load_all(this);
320  }
321  }
322 
323  root = gnc_book_get_root_account( book );
324  gnc_account_foreach_descendant(root, (AccountCb)xaccAccountBeginEdit,
325  nullptr);
326 
327  m_backend_registry.load_remaining(this);
328 
329  gnc_account_foreach_descendant(root, (AccountCb)xaccAccountCommitEdit,
330  nullptr);
331  }
332  else if (loadType == LOAD_TYPE_LOAD_ALL)
333  {
334  // Load all transactions
335  auto obe = m_backend_registry.get_object_backend (GNC_ID_TRANS);
336  obe->load_all (this);
337  }
338 
339  m_loading = FALSE;
340  std::for_each(m_postload_commodities.begin(), m_postload_commodities.end(),
341  [](gnc_commodity* comm) {
342  gnc_commodity_begin_edit(comm);
343  gnc_commodity_commit_edit(comm);
344  });
345  m_postload_commodities.clear();
346  /* We deferred the transaction scrub while loading because having
347  * m_loading true prevents changes from being written back to the
348  * database. Do that now.
349  */
350  auto transactions = qof_book_get_collection (book, GNC_ID_TRANS);
351  qof_collection_foreach(transactions, scrub_txn_callback, nullptr);
352 
353  /* Mark the session as clean -- though it should never be marked
354  * dirty with this backend
355  */
357  finish_progress();
358 
359  LEAVE ("");
360 }
STRUCTS.
bool m_loading
We are performing an initial load.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
Definition: qofbook.cpp:383
QofBook * m_book
The primary, main open book.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1475
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition: qofbook.cpp:521
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1516

◆ object_in_db()

bool GncSqlBackend::object_in_db ( const char *  table_name,
QofIdTypeConst  obj_name,
const gpointer  pObject,
const EntryVec &  table 
) const
noexcept

Checks whether an object is in the database or not.

Parameters
table_nameDB table name
obj_nameQOF object type name
pObjectObject to be checked
tableDB table description
Returns
TRUE if the object is in the database, FALSE otherwise

Definition at line 832 of file gnc-sql-backend.cpp.

834 {
835  g_return_val_if_fail (table_name != nullptr, false);
836  g_return_val_if_fail (obj_name != nullptr, false);
837  g_return_val_if_fail (pObject != nullptr, false);
838 
839  /* SELECT * FROM */
840  auto sql = std::string{"SELECT "} + table[0]->name() + " FROM " + table_name;
841  auto stmt = create_statement_from_sql(sql.c_str());
842  assert (stmt != nullptr);
843 
844  /* WHERE */
845  PairVec values{get_object_values(obj_name, pObject, table)};
846  /* We want only the first item in the table, which should be the PK. */
847  values.resize(1);
848  stmt->add_where_cond(obj_name, values);
849  auto result = execute_select_statement (stmt);
850  return (result != nullptr && result->size() > 0);
851 }
GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr &stmt) const noexcept
Executes an SQL SELECT statement and returns the result rows.

◆ reset_version_info()

bool GncSqlBackend::reset_version_info ( )
noexcept

Resets the version table information by removing all version table info.

It also recreates the version table in the db.

Parameters
beBackend struct
Returns
TRUE if successful, FALSE if error

Definition at line 706 of file gnc-sql-backend.cpp.

707 {
708  bool ok = create_table (VERSION_TABLE_NAME, version_table);
709  m_versions.clear();
710  set_table_version ("Gnucash", gnc_prefs_get_long_version ());
711  set_table_version ("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
712  return ok;
713 }
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.
VersionVec m_versions
Version number for each table.

◆ rollback()

void GncSqlBackend::rollback ( QofInstance inst)
overridevirtual

Object editing has been cancelled.

Parameters
instObject being edited

Reimplemented from QofBackend.

Definition at line 552 of file gnc-sql-backend.cpp.

553 {
554  //g_return_if_fail (inst != NULL);
555 
556  //ENTER (" ");
557  //LEAVE ("");
558 }

◆ save_commodity()

bool GncSqlBackend::save_commodity ( gnc_commodity *  comm)
noexcept

Ensure that a commodity referenced in another object is in fact saved in the database.

Parameters
commThe commodity in question
Returns
true if the commodity needed to be saved.

Definition at line 882 of file gnc-sql-backend.cpp.

883 {
884  if (comm == nullptr) return false;
885  QofInstance* inst = QOF_INSTANCE(comm);
886  auto obe = m_backend_registry.get_object_backend(std::string(inst->e_type));
887  if (obe && !obe->instance_in_db(this, inst))
888  return obe->commit(this, inst);
889  return true;
890 }
QofIdType e_type
Entity type.
Definition: qofinstance.h:75

◆ set_table_version()

bool GncSqlBackend::set_table_version ( const std::string &  table_name,
uint_t  version 
)
noexcept

Registers the version for a table.

Registering involves updating the db version table and also the hash table.

Parameters
beBackend struct
table_nameTable name
versionVersion number
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 751 of file gnc-sql-backend.cpp.

753 {
754  g_return_val_if_fail (version > 0, false);
755 
756  unsigned int cur_version{0};
757  std::stringstream sql;
758  auto ver_entry = std::find_if(m_versions.begin(), m_versions.end(),
759  [table_name](const VersionPair& ver) {
760  return ver.first == table_name; });
761  if (ver_entry != m_versions.end())
762  cur_version = ver_entry->second;
763  if (cur_version != version)
764  {
765  if (cur_version == 0)
766  {
767  sql << "INSERT INTO " << VERSION_TABLE_NAME << " VALUES('" <<
768  table_name << "'," << version <<")";
769  m_versions.push_back(std::make_pair(table_name, version));
770  }
771  else
772  {
773  sql << "UPDATE " << VERSION_TABLE_NAME << " SET " <<
774  VERSION_COL_NAME << "=" << version << " WHERE " <<
775  TABLE_COL_NAME << "='" << table_name << "'";
776  ver_entry->second = version;
777  }
778  auto stmt = create_statement_from_sql(sql.str());
779  auto status = execute_nonselect_statement (stmt);
780  if (status == -1)
781  {
782  PERR ("SQL error: %s\n", sql.str().c_str());
784  return false;
785  }
786  }
787 
788  return true;
789 }
VersionVec m_versions
Version number for each table.
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
error in response from server
Definition: qofbackend.h:71

◆ sync()

void GncSqlBackend::sync ( QofBook *  book)
overridevirtual

Save the contents of a book to an SQL database.

Parameters
bookBook to be saved

Implements QofBackend.

Definition at line 472 of file gnc-sql-backend.cpp.

473 {
474  g_return_if_fail (book != NULL);
475  g_return_if_fail (m_conn != nullptr);
476 
478  ENTER ("book=%p, sql_be->book=%p", book, m_book);
479  update_progress(101.0);
480 
481  /* Create new tables */
482  m_is_pristine_db = true;
483  create_tables();
484 
485  /* Save all contents */
486  m_book = book;
487  auto is_ok = m_conn->begin_transaction();
488 
489  // FIXME: should write the set of commodities that are used
490  // write_commodities(sql_be, book);
491  if (is_ok)
492  {
493  auto obe = m_backend_registry.get_object_backend(GNC_ID_BOOK);
494  is_ok = obe->commit (this, QOF_INSTANCE (book));
495  }
496  if (is_ok)
497  {
498  is_ok = write_accounts();
499  }
500  if (is_ok)
501  {
502  is_ok = write_transactions();
503  }
504  if (is_ok)
505  {
506  is_ok = write_template_transactions();
507  }
508  if (is_ok)
509  {
510  is_ok = write_schedXactions();
511  }
512  if (is_ok)
513  {
514  for (auto entry : m_backend_registry)
515  std::get<1>(entry)->write (this);
516  }
517  if (is_ok)
518  {
519  is_ok = m_conn->commit_transaction();
520  }
521  if (is_ok)
522  {
523  m_is_pristine_db = false;
524 
525  /* Mark the session as clean -- though it shouldn't ever get
526  * marked dirty with this backend
527  */
529  }
530  else
531  {
534  }
535  finish_progress();
536  LEAVE ("book=%p", book);
537 }
void create_tables() noexcept
Create/update all tables in the database.
GncSqlConnection * m_conn
SQL connection.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
error in response from server
Definition: qofbackend.h:71
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
Definition: qofbook.cpp:383
QofBook * m_book
The primary, main open book.
virtual bool commit_transaction() noexcept=0
Returns TRUE if successful, FALSE if error.
bool m_is_pristine_db
Are we saving to a new pristine db?
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
virtual bool begin_transaction() noexcept=0
Returns TRUE if successful, false if error.
virtual bool rollback_transaction() noexcept=0
Returns TRUE if successful, FALSE if error.
bool reset_version_info() noexcept
Resets the version table information by removing all version table info.
void set_error(QofBackendError err)
Set the error value only if there isn&#39;t already an error already.
Definition: qof-backend.cpp:56

◆ upgrade_table()

void GncSqlBackend::upgrade_table ( const std::string &  table_name,
const EntryVec &  col_table 
)
noexcept

Upgrades a table to a new structure.

The upgrade is done by creating a new table with the new structure, SELECTing the old data into the new table, deleting the old table, then renaming the new table. Therefore, this will only work if the new table structure is similar enough to the old table that the SELECT will work.

Parameters
table_nameSQL table name
col_tableColumn table

Definition at line 792 of file gnc-sql-backend.cpp.

794 {
795  DEBUG ("Upgrading %s table\n", table_name.c_str());
796 
797  auto temp_table_name = table_name + "_new";
798  create_table (temp_table_name, col_table);
799  std::stringstream sql;
800  sql << "INSERT INTO " << temp_table_name << " SELECT * FROM " << table_name;
801  auto stmt = create_statement_from_sql(sql.str());
802  execute_nonselect_statement(stmt);
803 
804  sql.str("");
805  sql << "DROP TABLE " << table_name;
806  stmt = create_statement_from_sql(sql.str());
807  execute_nonselect_statement(stmt);
808 
809  sql.str("");
810  sql << "ALTER TABLE " << temp_table_name << " RENAME TO " << table_name;
811  stmt = create_statement_from_sql(sql.str());
812  execute_nonselect_statement(stmt);
813 }
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264

The documentation for this class was generated from the following files: