GnuCash c935c2f+
Loading...
Searching...
No Matches
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.
 
void sync (QofBook *) override
 Save the contents of a book to an SQL database.
 
void begin (QofInstance *) override
 An object is about to be edited.
 
void commit (QofInstance *) override
 Object editing is complete and the object should be saved.
 
void rollback (QofInstance *) override
 Object editing has been cancelled.
 
void connect (GncSqlConnection *conn) noexcept
 Connect the backend to a GncSqlConnection.
 
void init_version_info () noexcept
 Initializes DB table version information.
 
bool reset_version_info () noexcept
 Resets the version table information by removing all version table info.
 
void finalize_version_info () noexcept
 Finalizes DB table version information.
 
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.
 
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.
 
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.
 
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.
 
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.
 
void upgrade_table (const std::string &table_name, const EntryVec &col_table) noexcept
 Upgrades a table to a new structure.
 
uint_t get_table_version (const std::string &table_name) const noexcept
 Returns the version number for a DB table.
 
bool set_table_version (const std::string &table_name, uint_t version) noexcept
 Registers the version for a table.
 
void commodity_for_postload_processing (gnc_commodity *)
 Register a commodity to be committed after loading is complete.
 
GncSqlObjectBackendPtr get_object_backend (const std::string &type) const noexcept
 Get the GncSqlObjectBackend for the indicated type.
 
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.
 
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.
 
bool save_commodity (gnc_commodity *comm) noexcept
 Ensure that a commodity referenced in another object is in fact saved in the database.
 
QofBookbook () 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.
 
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.
 
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.
 
QofBookm_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.
 

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.

Constructor & Destructor Documentation

◆ GncSqlBackend()

GncSqlBackend::GncSqlBackend ( GncSqlConnection conn,
QofBook book 
)

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

81 :
82 QofBackend {}, m_conn{conn}, m_book{book}, m_loading{false},
83 m_in_query{false}, m_is_pristine_db{false}
84{
85 if (conn != nullptr)
86 connect (conn);
87}
QofBook * m_book
The primary, main open book.
GncSqlConnection * m_conn
SQL connection.
bool m_is_pristine_db
Are we saving to a new pristine db?
bool m_loading
We are performing an initial load.
bool m_in_query
We are processing a query.
void connect(GncSqlConnection *conn) noexcept
Connect the backend to a GncSqlConnection.

◆ ~GncSqlBackend()

GncSqlBackend::~GncSqlBackend ( )
virtual

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

90{
91 connect(nullptr);
92}

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}
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}

◆ book()

QofBook * GncSqlBackend::book ( ) const
inlinenoexcept

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

235{ return m_book; }

◆ 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 {
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);
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
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}
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.
virtual bool commit_transaction() noexcept=0
Returns TRUE if successful, FALSE if error.
@ ERR_BACKEND_READONLY
cannot write to file/directory
Definition qofbackend.h:68
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
Definition qofbook.cpp:497
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.
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
QofIdType e_type
Entity type.
Definition qofinstance.h:75
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#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 set_error(QofBackendError err)
Set the error value only if there isn't already an error already.

◆ 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}
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}
virtual bool create_index(const std::string &, const std::string &, const EntryVec &) const noexcept=0
Returns TRUE if successful, FALSE if error.

◆ create_statement_from_sql()

GncSqlStatementPtr GncSqlBackend::create_statement_from_sql ( const std::string &  str) const
noexcept

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

105{
106 auto stmt = m_conn ? m_conn->create_statement_from_sql(str) : nullptr;
107 if (stmt == nullptr)
108 {
109 PERR ("SQL error: %s\n", str.c_str());
111 }
112 return stmt;
113}
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
@ ERR_BACKEND_SERVER_ERR
error in response from server
Definition qofbackend.h:71

◆ 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}
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.

◆ create_tables()

void GncSqlBackend::create_tables ( )
noexcept

Create/update all tables in the database.

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

213{
214 for(auto entry : m_backend_registry)
215 {
216 update_progress(101.0);
217 std::get<1>(entry)->create_tables(this);
218 }
219}

◆ 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_nonselect_statement()

int GncSqlBackend::execute_nonselect_statement ( const GncSqlStatementPtr &  stmt) const
noexcept

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

129{
130 int result = m_conn ? m_conn->execute_nonselect_statement(stmt) : -1;
131 if (result == -1)
132 {
133 PERR ("SQL error: %s\n", stmt->to_sql());
135 }
136 return result;
137}
virtual int execute_nonselect_statement(const GncSqlStatementPtr &) noexcept=0
Returns false if error.

◆ 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}

◆ 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.

◆ finish_progress()

void GncSqlBackend::finish_progress ( ) const
noexcept

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

206{
207 if (m_percentage != nullptr)
208 (m_percentage) (nullptr, -1.0);
209}

◆ 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. */
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}

◆ 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}
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 */
352 auto transactions = qof_book_get_collection (book, GNC_ID_TRANS);
353 qof_collection_foreach(transactions, scrub_txn_callback, nullptr);
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}
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition Account.cpp:1516
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition Account.cpp:1475
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 xaccLogEnable(void)
document me
Definition TransLog.cpp:100
void xaccLogDisable(void)
document me
Definition TransLog.cpp:96
STRUCTS.

◆ 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.

◆ pristine()

bool GncSqlBackend::pristine ( ) const
inlinenoexcept

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

237{ return m_is_pristine_db; }

◆ quote_string()

std::string GncSqlBackend::quote_string ( const std::string &  str) const
noexcept

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

141{
142 g_return_val_if_fail (m_conn != nullptr, empty_string);
143 if (!m_conn)
144 return empty_string;
145 return m_conn->quote_string(str);
146}

◆ 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}

◆ 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}

◆ set_loading()

void GncSqlBackend::set_loading ( bool  loading)
inlinenoexcept

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

236{ m_loading = loading; }

◆ 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}

◆ 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;
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.
bool reset_version_info() noexcept
Resets the version table information by removing all version table info.

◆ update_progress()

void GncSqlBackend::update_progress ( double  pct) const
noexcept

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

199{
200 if (m_percentage != nullptr)
201 (m_percentage) (nullptr, pct);
202}

◆ 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}

Field Documentation

◆ m_book

QofBook* GncSqlBackend::m_book = nullptr
protected

The primary, main open book.

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

◆ m_conn

GncSqlConnection* GncSqlBackend::m_conn = nullptr
protected

SQL connection.

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

◆ m_in_query

bool GncSqlBackend::m_in_query
protected

We are processing a query.

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

◆ m_is_pristine_db

bool GncSqlBackend::m_is_pristine_db
protected

Are we saving to a new pristine db?

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

◆ m_loading

bool GncSqlBackend::m_loading
protected

We are performing an initial load.

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

◆ m_time_format

const char* GncSqlBackend::m_time_format = nullptr
protected

Server-specific date-time string format.

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

◆ m_versions

VersionVec GncSqlBackend::m_versions
protected

Version number for each table.

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


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