GnuCash  4.8a-176-g88ecf8dd1
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 65 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 185 of file gnc-sql-backend.cpp.

187 {
188  g_return_val_if_fail (m_conn != nullptr, false);
189 
190  ColVec info_vec;
191 
192  for (auto const& table_row : col_table)
193  {
194  table_row->add_to_table (info_vec);
195  }
196  return m_conn->add_columns_to_table(table_name, info_vec);
197 }
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 535 of file gnc-sql-backend.cpp.

536 {
537  //g_return_if_fail (inst != NULL);
538 
539  //ENTER (" ");
540  //LEAVE ("");
541 }

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

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

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

554 {
555  m_postload_commodities.push_back(commodity);
556 }

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

98 {
99  if (m_conn != nullptr && m_conn != conn)
100  delete m_conn;
102  m_conn = conn;
103 }
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 176 of file gnc-sql-backend.cpp.

179 {
180  g_return_val_if_fail (m_conn != nullptr, false);
181  return m_conn->create_index(index_name, table_name, col_table);
182 }
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 151 of file gnc-sql-backend.cpp.

153 {
154  g_return_val_if_fail (m_conn != nullptr, false);
155 
156  ColVec info_vec;
157 
158  for (auto const& table_row : col_table)
159  {
160  table_row->add_to_table (info_vec);
161  }
162  return m_conn->create_table (table_name, info_vec);
163 
164 }
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 167 of file gnc-sql-backend.cpp.

169 {
170  if (create_table (table_name, col_table))
171  return set_table_version (table_name, table_version);
172  return false;
173 }
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 847 of file gnc-sql-backend.cpp.

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

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

119 {
120  auto result = m_conn ? m_conn->execute_select_statement(stmt) : nullptr;
121  if (result == nullptr)
122  {
123  PERR ("SQL error: %s\n", stmt->to_sql());
125  }
126  return result;
127 }
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 713 of file gnc-sql-backend.cpp.

714 {
715  m_versions.clear();
716 }
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 559 of file gnc-sql-backend.cpp.

560 {
561  return m_backend_registry.get_object_backend(type);
562 }

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

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

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

280 {
281  Account* root;
282 
283  g_return_if_fail (book != NULL);
284 
285  ENTER ("sql_be=%p, book=%p", this, book);
286 
287  m_loading = TRUE;
288 
289  if (loadType == LOAD_TYPE_INITIAL_LOAD)
290  {
291  assert (m_book == nullptr);
292  m_book = book;
293 
294  auto num_types = m_backend_registry.size();
295  auto num_done = 0;
296 
297  /* Load any initial stuff. Some of this needs to happen in a certain order */
298  for (auto type : fixed_load_order)
299  {
300  num_done++;
301  auto obe = m_backend_registry.get_object_backend(type);
302  if (obe)
303  {
304  update_progress(num_done * 100 / num_types);
305  obe->load_all(this);
306  }
307  }
308  for (auto type : business_fixed_load_order)
309  {
310  num_done++;
311  auto obe = m_backend_registry.get_object_backend(type);
312  if (obe)
313  {
314  update_progress(num_done * 100 / num_types);
315  obe->load_all(this);
316  }
317  }
318 
319  root = gnc_book_get_root_account( book );
321  nullptr);
322 
323  m_backend_registry.load_remaining(this);
324 
326  nullptr);
327  }
328  else if (loadType == LOAD_TYPE_LOAD_ALL)
329  {
330  // Load all transactions
331  auto obe = m_backend_registry.get_object_backend (GNC_ID_TRANS);
332  obe->load_all (this);
333  }
334 
335  m_loading = FALSE;
336  std::for_each(m_postload_commodities.begin(), m_postload_commodities.end(),
337  [](gnc_commodity* comm) {
338  gnc_commodity_begin_edit(comm);
339  gnc_commodity_commit_edit(comm);
340  });
341  m_postload_commodities.clear();
342 
343  /* Mark the sessoion as clean -- though it should never be marked
344  * dirty with this backend
345  */
347  finish_progress();
348 
349  LEAVE ("");
350 }
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:3202
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:467
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:1430
#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:1471

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

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

699 {
700  bool ok = create_table (VERSION_TABLE_NAME, version_table);
701  m_versions.clear();
702  set_table_version ("Gnucash", gnc_prefs_get_long_version ());
703  set_table_version ("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
704  return ok;
705 }
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 544 of file gnc-sql-backend.cpp.

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

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

876 {
877  if (comm == nullptr) return false;
878  QofInstance* inst = QOF_INSTANCE(comm);
879  auto obe = m_backend_registry.get_object_backend(std::string(inst->e_type));
880  if (obe && !obe->instance_in_db(this, inst))
881  return obe->commit(this, inst);
882  return true;
883 }

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

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

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

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

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