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

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

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

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

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

565 {
566  m_postload_commodities.push_back(commodity);
567 }

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

96 {
97  if (m_conn != nullptr && m_conn != conn)
98  delete m_conn;
100  m_conn = conn;
101 }
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 174 of file gnc-sql-backend.cpp.

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

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

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

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

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

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

725 {
726  m_versions.clear();
727 }
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 570 of file gnc-sql-backend.cpp.

571 {
572  return m_backend_registry.get_object_backend(type);
573 }

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

731 {
732  /* If the db is pristine because it's being saved, the table does not exist. */
733  if (m_is_pristine_db)
734  return 0;
735 
736  auto version = std::find_if(m_versions.begin(), m_versions.end(),
737  [table_name](const VersionPair& version) {
738  return version.first == table_name; });
739  if (version != m_versions.end())
740  return version->second;
741  return 0;
742 }
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 676 of file gnc-sql-backend.cpp.

677 {
678  g_return_if_fail (m_conn != nullptr);
679  if (m_conn->does_table_exist (VERSION_TABLE_NAME))
680  {
681  std::string sql {"SELECT * FROM "};
682  sql += VERSION_TABLE_NAME;
683  auto stmt = m_conn->create_statement_from_sql(sql);
684  auto result = m_conn->execute_select_statement (stmt);
685  for (const auto& row : *result)
686  {
687  auto name = row.get_string_at_col (TABLE_COL_NAME);
688  auto version = row.get_int_at_col (VERSION_COL_NAME);
689  if (name && version)
690  m_versions.push_back(std::make_pair(*name, static_cast<unsigned int>(*version)));
691  }
692  }
693  else
694  {
695  create_table (VERSION_TABLE_NAME, version_table);
696  set_table_version("Gnucash", gnc_prefs_get_long_version ());
697  set_table_version("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
698  }
699 }
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 284 of file gnc-sql-backend.cpp.

285 {
286  Account* root;
287 
288  g_return_if_fail (book != NULL);
289 
290  ENTER ("sql_be=%p, book=%p", this, book);
291 
292  m_loading = TRUE;
293 
294  if (loadType == LOAD_TYPE_INITIAL_LOAD)
295  {
296  assert (m_book == nullptr);
297  m_book = book;
298 
299  auto num_types = m_backend_registry.size();
300  auto num_done = 0;
301 
302  /* Load any initial stuff. Some of this needs to happen in a certain order */
303  for (const auto& type : fixed_load_order)
304  {
305  num_done++;
306  auto obe = m_backend_registry.get_object_backend(type);
307  if (obe)
308  {
309  update_progress(num_done * 100 / num_types);
310  obe->load_all(this);
311  }
312  }
313  for (const auto& type : business_fixed_load_order)
314  {
315  num_done++;
316  auto obe = m_backend_registry.get_object_backend(type);
317  if (obe)
318  {
319  update_progress(num_done * 100 / num_types);
320  obe->load_all(this);
321  }
322  }
323 
324  root = gnc_book_get_root_account( book );
325  gnc_account_foreach_descendant(root, (AccountCb)xaccAccountBeginEdit,
326  nullptr);
327 
328  m_backend_registry.load_remaining(this);
329 
330  gnc_account_foreach_descendant(root, (AccountCb)xaccAccountCommitEdit,
331  nullptr);
332  }
333  else if (loadType == LOAD_TYPE_LOAD_ALL)
334  {
335  // Load all transactions
336  auto obe = m_backend_registry.get_object_backend (GNC_ID_TRANS);
337  obe->load_all (this);
338  }
339 
340  m_loading = FALSE;
341  std::for_each(m_postload_commodities.begin(), m_postload_commodities.end(),
342  [](gnc_commodity* comm) {
343  gnc_commodity_begin_edit(comm);
344  gnc_commodity_commit_edit(comm);
345  });
346  m_postload_commodities.clear();
347  /* We deferred the transaction scrub while loading because having
348  * m_loading true prevents changes from being written back to the
349  * database. Do that now.
350  */
351  xaccLogDisable();
352  auto transactions = qof_book_get_collection (book, GNC_ID_TRANS);
353  qof_collection_foreach(transactions, scrub_txn_callback, nullptr);
354  xaccLogEnable();
355 
356  /* Mark the session as clean -- though it should never be marked
357  * dirty with this backend
358  */
360  finish_progress();
361 
362  LEAVE ("");
363 }
STRUCTS.
void xaccLogDisable(void)
document me
Definition: TransLog.cpp:95
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
void xaccLogEnable(void)
document me
Definition: TransLog.cpp:99

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

837 {
838  g_return_val_if_fail (table_name != nullptr, false);
839  g_return_val_if_fail (obj_name != nullptr, false);
840  g_return_val_if_fail (pObject != nullptr, false);
841 
842  /* SELECT * FROM */
843  auto sql = std::string{"SELECT "} + table[0]->name() + " FROM " + table_name;
844  auto stmt = create_statement_from_sql(sql.c_str());
845  assert (stmt != nullptr);
846 
847  /* WHERE */
848  PairVec values{get_object_values(obj_name, pObject, table)};
849  /* We want only the first item in the table, which should be the PK. */
850  values.resize(1);
851  stmt->add_where_cond(obj_name, values);
852  auto result = execute_select_statement (stmt);
853  return (result != nullptr && result->size() > 0);
854 }
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 709 of file gnc-sql-backend.cpp.

710 {
711  bool ok = create_table (VERSION_TABLE_NAME, version_table);
712  m_versions.clear();
713  set_table_version ("Gnucash", gnc_prefs_get_long_version ());
714  set_table_version ("Gnucash-Resave", GNUCASH_RESAVE_VERSION);
715  return ok;
716 }
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 555 of file gnc-sql-backend.cpp.

556 {
557  //g_return_if_fail (inst != NULL);
558 
559  //ENTER (" ");
560  //LEAVE ("");
561 }

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

886 {
887  if (comm == nullptr) return false;
888  QofInstance* inst = QOF_INSTANCE(comm);
889  auto obe = m_backend_registry.get_object_backend(std::string(inst->e_type));
890  if (obe && !obe->instance_in_db(this, inst))
891  return obe->commit(this, inst);
892  return true;
893 }
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 754 of file gnc-sql-backend.cpp.

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

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

797 {
798  DEBUG ("Upgrading %s table\n", table_name.c_str());
799 
800  auto temp_table_name = table_name + "_new";
801  create_table (temp_table_name, col_table);
802  std::stringstream sql;
803  sql << "INSERT INTO " << temp_table_name << " SELECT * FROM " << table_name;
804  auto stmt = create_statement_from_sql(sql.str());
805  execute_nonselect_statement(stmt);
806 
807  sql.str("");
808  sql << "DROP TABLE " << table_name;
809  stmt = create_statement_from_sql(sql.str());
810  execute_nonselect_statement(stmt);
811 
812  sql.str("");
813  sql << "ALTER TABLE " << temp_table_name << " RENAME TO " << table_name;
814  stmt = create_statement_from_sql(sql.str());
815  execute_nonselect_statement(stmt);
816 }
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: