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 530 of file gnc-sql-backend.cpp.

531 {
532  //g_return_if_fail (inst != NULL);
533 
534  //ENTER (" ");
535  //LEAVE ("");
536 }

◆ 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 564 of file gnc-sql-backend.cpp.

565 {
566  gboolean is_dirty;
567  gboolean is_destroying;
568  gboolean is_infant;
569 
570  g_return_if_fail (inst != NULL);
571  g_return_if_fail (m_conn != nullptr);
572 
574  {
576  (void)m_conn->rollback_transaction ();
577  return;
578  }
579  /* During initial load where objects are being created, don't commit
580  anything, but do mark the object as clean. */
581  if (m_loading)
582  {
583  qof_instance_mark_clean (inst);
584  return;
585  }
586 
587  // The engine has a PriceDB object but it isn't in the database
588  if (strcmp (inst->e_type, "PriceDB") == 0)
589  {
590  qof_instance_mark_clean (inst);
592  return;
593  }
594 
595  ENTER (" ");
596 
597  is_dirty = qof_instance_get_dirty_flag (inst);
598  is_destroying = qof_instance_get_destroying (inst);
599  is_infant = qof_instance_get_infant (inst);
600 
601  DEBUG ("%s dirty = %d, do_free = %d, infant = %d\n",
602  (inst->e_type ? inst->e_type : "(null)"),
603  is_dirty, is_destroying, is_infant);
604 
605  if (!is_dirty && !is_destroying)
606  {
607  LEAVE ("!dirty OR !destroying");
608  return;
609  }
610 
611  if (!m_conn->begin_transaction ())
612  {
613  PERR ("begin_transaction failed\n");
614  LEAVE ("Rolled back - database transaction begin error");
615  return;
616  }
617 
618  bool is_ok = true;
619 
620  auto obe = m_backend_registry.get_object_backend(std::string{inst->e_type});
621  if (obe != nullptr)
622  is_ok = obe->commit(this, inst);
623  else
624  {
625  PERR ("Unknown object type '%s'\n", inst->e_type);
626  (void)m_conn->rollback_transaction ();
627 
628  // Don't let unknown items still mark the book as being dirty
630  qof_instance_mark_clean (inst);
631  LEAVE ("Rolled back - unknown object type");
632  return;
633  }
634  if (!is_ok)
635  {
636  // Error - roll it back
637  (void)m_conn->rollback_transaction();
638 
639  // This *should* leave things marked dirty
640  LEAVE ("Rolled back - database error");
641  return;
642  }
643 
644  (void)m_conn->commit_transaction ();
645 
647  qof_instance_mark_clean (inst);
648 
649  LEAVE ("");
650 }
#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 548 of file gnc-sql-backend.cpp.

549 {
550  m_postload_commodities.push_back(commodity);
551 }

◆ 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 841 of file gnc-sql-backend.cpp.

844 {
845  GncSqlStatementPtr stmt;
846 
847  g_return_val_if_fail (table_name != nullptr, false);
848  g_return_val_if_fail (obj_name != nullptr, false);
849  g_return_val_if_fail (pObject != nullptr, false);
850 
851  switch(op)
852  {
853  case OP_DB_INSERT:
854  stmt = build_insert_statement (table_name, obj_name, pObject, table);
855  break;
856  case OP_DB_UPDATE:
857  stmt = build_update_statement (table_name, obj_name, pObject, table);
858  break;
859  case OP_DB_DELETE:
860  stmt = build_delete_statement (table_name, obj_name, pObject, table);
861  break;
862  }
863  if (stmt == nullptr)
864  return false;
865  return (execute_nonselect_statement(stmt) != -1);
866 }

◆ 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 708 of file gnc-sql-backend.cpp.

709 {
710  m_versions.clear();
711 }
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 554 of file gnc-sql-backend.cpp.

555 {
556  return m_backend_registry.get_object_backend(type);
557 }

◆ 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 714 of file gnc-sql-backend.cpp.

715 {
716  /* If the db is pristine because it's being saved, the table does not exist. */
717  if (m_is_pristine_db)
718  return 0;
719 
720  auto version = std::find_if(m_versions.begin(), m_versions.end(),
721  [table_name](const VersionPair& version) {
722  return version.first == table_name; });
723  if (version != m_versions.end())
724  return version->second;
725  return 0;
726 }
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 660 of file gnc-sql-backend.cpp.

661 {
662  g_return_if_fail (m_conn != nullptr);
663  if (m_conn->does_table_exist (VERSION_TABLE_NAME))
664  {
665  std::string sql {"SELECT * FROM "};
666  sql += VERSION_TABLE_NAME;
667  auto stmt = m_conn->create_statement_from_sql(sql);
668  auto result = m_conn->execute_select_statement (stmt);
669  for (const auto& row : *result)
670  {
671  auto name = row.get_string_at_col (TABLE_COL_NAME);
672  auto version = row.get_int_at_col (VERSION_COL_NAME);
673  if (name && version)
674  m_versions.push_back(std::make_pair(*name, static_cast<unsigned int>(*version)));
675  }
676  }
677  else
678  {
679  create_table (VERSION_TABLE_NAME, version_table);
680  set_table_version("Gnucash", gnc_prefs_get_long_version ());
681  set_table_version("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
682  }
683 }
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 276 of file gnc-sql-backend.cpp.

277 {
278  Account* root;
279 
280  g_return_if_fail (book != NULL);
281 
282  ENTER ("sql_be=%p, book=%p", this, book);
283 
284  m_loading = TRUE;
285 
286  if (loadType == LOAD_TYPE_INITIAL_LOAD)
287  {
288  assert (m_book == nullptr);
289  m_book = book;
290 
291  auto num_types = m_backend_registry.size();
292  auto num_done = 0;
293 
294  /* Load any initial stuff. Some of this needs to happen in a certain order */
295  for (const auto& type : fixed_load_order)
296  {
297  num_done++;
298  auto obe = m_backend_registry.get_object_backend(type);
299  if (obe)
300  {
301  update_progress(num_done * 100 / num_types);
302  obe->load_all(this);
303  }
304  }
305  for (const auto& type : business_fixed_load_order)
306  {
307  num_done++;
308  auto obe = m_backend_registry.get_object_backend(type);
309  if (obe)
310  {
311  update_progress(num_done * 100 / num_types);
312  obe->load_all(this);
313  }
314  }
315 
316  root = gnc_book_get_root_account( book );
318  nullptr);
319 
320  m_backend_registry.load_remaining(this);
321 
323  nullptr);
324  }
325  else if (loadType == LOAD_TYPE_LOAD_ALL)
326  {
327  // Load all transactions
328  auto obe = m_backend_registry.get_object_backend (GNC_ID_TRANS);
329  obe->load_all (this);
330  }
331 
332  m_loading = FALSE;
333  std::for_each(m_postload_commodities.begin(), m_postload_commodities.end(),
334  [](gnc_commodity* comm) {
335  gnc_commodity_begin_edit(comm);
336  gnc_commodity_commit_edit(comm);
337  });
338  m_postload_commodities.clear();
339 
340  /* Mark the session as clean -- though it should never be marked
341  * dirty with this backend
342  */
344  finish_progress();
345 
346  LEAVE ("");
347 }
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
This method will traverse all children of this accounts and their descendants, calling &#39;func&#39; on each...
Definition: Account.cpp:3195
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:1479
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1520

◆ 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 819 of file gnc-sql-backend.cpp.

821 {
822  g_return_val_if_fail (table_name != nullptr, false);
823  g_return_val_if_fail (obj_name != nullptr, false);
824  g_return_val_if_fail (pObject != nullptr, false);
825 
826  /* SELECT * FROM */
827  auto sql = std::string{"SELECT "} + table[0]->name() + " FROM " + table_name;
828  auto stmt = create_statement_from_sql(sql.c_str());
829  assert (stmt != nullptr);
830 
831  /* WHERE */
832  PairVec values{get_object_values(obj_name, pObject, table)};
833  /* We want only the first item in the table, which should be the PK. */
834  values.resize(1);
835  stmt->add_where_cond(obj_name, values);
836  auto result = execute_select_statement (stmt);
837  return (result != nullptr && result->size() > 0);
838 }
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 693 of file gnc-sql-backend.cpp.

694 {
695  bool ok = create_table (VERSION_TABLE_NAME, version_table);
696  m_versions.clear();
697  set_table_version ("Gnucash", gnc_prefs_get_long_version ());
698  set_table_version ("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
699  return ok;
700 }
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 539 of file gnc-sql-backend.cpp.

540 {
541  //g_return_if_fail (inst != NULL);
542 
543  //ENTER (" ");
544  //LEAVE ("");
545 }

◆ 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 869 of file gnc-sql-backend.cpp.

870 {
871  if (comm == nullptr) return false;
872  QofInstance* inst = QOF_INSTANCE(comm);
873  auto obe = m_backend_registry.get_object_backend(std::string(inst->e_type));
874  if (obe && !obe->instance_in_db(this, inst))
875  return obe->commit(this, inst);
876  return true;
877 }
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 738 of file gnc-sql-backend.cpp.

740 {
741  g_return_val_if_fail (version > 0, false);
742 
743  unsigned int cur_version{0};
744  std::stringstream sql;
745  auto ver_entry = std::find_if(m_versions.begin(), m_versions.end(),
746  [table_name](const VersionPair& ver) {
747  return ver.first == table_name; });
748  if (ver_entry != m_versions.end())
749  cur_version = ver_entry->second;
750  if (cur_version != version)
751  {
752  if (cur_version == 0)
753  {
754  sql << "INSERT INTO " << VERSION_TABLE_NAME << " VALUES('" <<
755  table_name << "'," << version <<")";
756  m_versions.push_back(std::make_pair(table_name, version));
757  }
758  else
759  {
760  sql << "UPDATE " << VERSION_TABLE_NAME << " SET " <<
761  VERSION_COL_NAME << "=" << version << " WHERE " <<
762  TABLE_COL_NAME << "='" << table_name << "'";
763  ver_entry->second = version;
764  }
765  auto stmt = create_statement_from_sql(sql.str());
766  auto status = execute_nonselect_statement (stmt);
767  if (status == -1)
768  {
769  PERR ("SQL error: %s\n", sql.str().c_str());
771  return false;
772  }
773  }
774 
775  return true;
776 }
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 459 of file gnc-sql-backend.cpp.

460 {
461  g_return_if_fail (book != NULL);
462  g_return_if_fail (m_conn != nullptr);
463 
465  ENTER ("book=%p, sql_be->book=%p", book, m_book);
466  update_progress(101.0);
467 
468  /* Create new tables */
469  m_is_pristine_db = true;
470  create_tables();
471 
472  /* Save all contents */
473  m_book = book;
474  auto is_ok = m_conn->begin_transaction();
475 
476  // FIXME: should write the set of commodities that are used
477  // write_commodities(sql_be, book);
478  if (is_ok)
479  {
480  auto obe = m_backend_registry.get_object_backend(GNC_ID_BOOK);
481  is_ok = obe->commit (this, QOF_INSTANCE (book));
482  }
483  if (is_ok)
484  {
485  is_ok = write_accounts();
486  }
487  if (is_ok)
488  {
489  is_ok = write_transactions();
490  }
491  if (is_ok)
492  {
493  is_ok = write_template_transactions();
494  }
495  if (is_ok)
496  {
497  is_ok = write_schedXactions();
498  }
499  if (is_ok)
500  {
501  for (auto entry : m_backend_registry)
502  std::get<1>(entry)->write (this);
503  }
504  if (is_ok)
505  {
506  is_ok = m_conn->commit_transaction();
507  }
508  if (is_ok)
509  {
510  m_is_pristine_db = false;
511 
512  /* Mark the session as clean -- though it shouldn't ever get
513  * marked dirty with this backend
514  */
516  }
517  else
518  {
521  }
522  finish_progress();
523  LEAVE ("book=%p", book);
524 }
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 779 of file gnc-sql-backend.cpp.

781 {
782  DEBUG ("Upgrading %s table\n", table_name.c_str());
783 
784  auto temp_table_name = table_name + "_new";
785  create_table (temp_table_name, col_table);
786  std::stringstream sql;
787  sql << "INSERT INTO " << temp_table_name << " SELECT * FROM " << table_name;
788  auto stmt = create_statement_from_sql(sql.str());
789  execute_nonselect_statement(stmt);
790 
791  sql.str("");
792  sql << "DROP TABLE " << table_name;
793  stmt = create_statement_from_sql(sql.str());
794  execute_nonselect_statement(stmt);
795 
796  sql.str("");
797  sql << "ALTER TABLE " << temp_table_name << " RENAME TO " << table_name;
798  stmt = create_statement_from_sql(sql.str());
799  execute_nonselect_statement(stmt);
800 }
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: