mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Make conn_table_operation and add_columns_ddl members of GncDbiSqlConnection.
So they don't need to be friends.
This commit is contained in:
parent
6f67e2dd1a
commit
d1fd223f9f
@ -1344,98 +1344,6 @@ save_may_clobber_data (QofBackend* qbe)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a specified SQL operation on every table in a
|
||||
* database. Possible operations are:
|
||||
* * drop: to DROP all tables from the database
|
||||
* * empty: to DELETE all records from each table in the database.
|
||||
* * backup: Rename every table from "name" to "name_back"
|
||||
* * drop_backup: DROP the backup tables.
|
||||
* * rollback: DROP the new table "name" and rename "name_back" to
|
||||
* "name", restoring the database to its previous state.
|
||||
*
|
||||
* The intent of the last two is to be able to move an existing table
|
||||
* aside, query its contents with a transformation (in 2.4.x this is
|
||||
* already done as the contents are loaded completely when a Qof
|
||||
* session is started), save them to a new table according to a new
|
||||
* database format, and finally drop the backup table; if there's an
|
||||
* error during the process, rollback allows returning the table to
|
||||
* its original state.
|
||||
*
|
||||
* @param sql_conn: The sql connection (via dbi) to which the
|
||||
* transactions will be sent
|
||||
* @param tables: GList of tables to operate on.
|
||||
* @param op: The operation to perform.
|
||||
* @return Success (TRUE) or failure.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
conn_table_operation (GncSqlConnection* sql_conn,
|
||||
std::vector<std::string> table_name_list,
|
||||
TableOpType op)
|
||||
{
|
||||
gboolean result = TRUE;
|
||||
GncDbiSqlConnection* conn = (GncDbiSqlConnection*) (sql_conn);
|
||||
const gchar* dbname = dbi_conn_get_option (conn->m_conn, "dbname");
|
||||
|
||||
g_return_val_if_fail (!table_name_list.empty(), FALSE);
|
||||
|
||||
for (auto table : table_name_list)
|
||||
{
|
||||
dbi_result result;
|
||||
auto table_name = table.c_str();
|
||||
/* Ignore the lock table */
|
||||
if (g_strcmp0 (table_name, lock_table) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
do
|
||||
{
|
||||
conn->init_error ();
|
||||
switch (op)
|
||||
{
|
||||
case rollback:
|
||||
{
|
||||
auto full_table_name_list =
|
||||
conn->m_provider->get_table_list (conn->m_conn, dbname);
|
||||
if (std::find (full_table_name_list.begin(),
|
||||
full_table_name_list.end(),
|
||||
table_name) != full_table_name_list.end())
|
||||
{
|
||||
result = dbi_conn_queryf (conn->m_conn, "DROP TABLE %s",
|
||||
table_name);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
case backup:
|
||||
case drop_backup:
|
||||
result = conn->table_manage_backup (table_name, op);
|
||||
break;
|
||||
case empty:
|
||||
result = dbi_conn_queryf (conn->m_conn, "DELETE FROM TABLE %s",
|
||||
table_name);
|
||||
break;
|
||||
case drop:
|
||||
default:
|
||||
result = dbi_conn_queryf (conn->m_conn, "DROP TABLE %s",
|
||||
table_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (conn->m_retry);
|
||||
if (result != nullptr)
|
||||
{
|
||||
if (dbi_result_free (result) < 0)
|
||||
{
|
||||
PERR ("Error in dbi_result_free() result\n");
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely resave a database by renaming all of its tables, recreating
|
||||
@ -1459,10 +1367,10 @@ gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book)
|
||||
ENTER ("book=%p, primary=%p", book, be->m_book);
|
||||
auto dbname = dbi_conn_get_option (conn->conn(), "dbname");
|
||||
auto table_list = conn->m_provider->get_table_list (conn->conn(), dbname);
|
||||
if (!conn_table_operation (conn, table_list, backup))
|
||||
if (!conn->table_operation (table_list, backup))
|
||||
{
|
||||
qof_backend_set_error (qbe, ERR_BACKEND_SERVER_ERR);
|
||||
conn_table_operation (conn, table_list, rollback);
|
||||
conn->table_operation (table_list, rollback);
|
||||
LEAVE ("Failed to rename tables");
|
||||
return;
|
||||
}
|
||||
@ -1474,7 +1382,7 @@ gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book)
|
||||
if (DBI_ERROR_NONE != dbi_conn_error (conn->m_conn, &errmsg))
|
||||
{
|
||||
qof_backend_set_error (qbe, ERR_BACKEND_SERVER_ERR);
|
||||
conn_table_operation (conn, table_list, rollback);
|
||||
conn->table_operation (table_list, rollback);
|
||||
LEAVE ("Failed to drop indexes %s", errmsg);
|
||||
return;
|
||||
}
|
||||
@ -1483,11 +1391,11 @@ gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book)
|
||||
gnc_sql_sync_all (be, book);
|
||||
if (qof_backend_check_error (qbe))
|
||||
{
|
||||
conn_table_operation (conn, table_list, rollback);
|
||||
conn->table_operation (table_list, rollback);
|
||||
LEAVE ("Failed to create new database tables");
|
||||
return;
|
||||
}
|
||||
conn_table_operation (conn, table_list, drop_backup);
|
||||
conn->table_operation (table_list, drop_backup);
|
||||
LEAVE ("book=%p", book);
|
||||
}
|
||||
/* ================================================================= */
|
||||
@ -1915,28 +1823,6 @@ GncDbiSqlResult::size() const noexcept
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
std::string
|
||||
add_columns_ddl(const GncSqlConnection* conn,
|
||||
const std::string& table_name,
|
||||
const ColVec& info_vec)
|
||||
{
|
||||
std::string ddl;
|
||||
const GncDbiSqlConnection* dbi_conn = dynamic_cast<decltype(dbi_conn)>(conn);
|
||||
|
||||
g_return_val_if_fail (conn != nullptr, nullptr);
|
||||
ddl += "ALTER TABLE " + table_name;
|
||||
for (auto const& info : info_vec)
|
||||
{
|
||||
if (info != *info_vec.begin())
|
||||
{
|
||||
ddl += ", ";
|
||||
}
|
||||
ddl += "ADD COLUMN ";
|
||||
dbi_conn->m_provider->append_col_def (ddl, info);
|
||||
}
|
||||
return ddl;
|
||||
}
|
||||
|
||||
template<> void
|
||||
GncDbiProviderImpl<DbType::DBI_SQLITE>::append_col_def(std::string& ddl,
|
||||
const GncSqlColumnInfo& info)
|
||||
|
@ -160,13 +160,11 @@ public:
|
||||
dbi_result table_manage_backup(const std::string& table_name, TableOpType op);
|
||||
/* FIXME: These three friend functions should really be members, but doing
|
||||
* that is too invasive just yet. */
|
||||
friend gboolean conn_table_operation (GncSqlConnection* sql_conn,
|
||||
std::vector<std::string> table_name_list,
|
||||
TableOpType op);
|
||||
bool table_operation (const std::vector<std::string>& table_name_list,
|
||||
TableOpType op) noexcept;
|
||||
std::string add_columns_ddl(const std::string& table_name,
|
||||
const ColVec& info_vec) const noexcept;
|
||||
friend void gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book);
|
||||
friend std::string add_columns_ddl(const GncSqlConnection* conn,
|
||||
const std::string& table_name,
|
||||
const ColVec& info_vec);
|
||||
|
||||
private:
|
||||
QofBackend* m_qbe;
|
||||
@ -195,8 +193,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
gboolean conn_table_operation (GncSqlConnection* sql_conn,
|
||||
GSList* table_name_list, TableOpType op);
|
||||
void gnc_dbi_safe_sync_all (QofBackend* qbe, QofBook* book);
|
||||
std::string add_columns_ddl(const GncSqlConnection* conn,
|
||||
const std::string& table_name,
|
||||
|
@ -390,7 +390,7 @@ GncDbiSqlConnection::add_columns_to_table(const std::string& table_name,
|
||||
const ColVec& info_vec)
|
||||
const noexcept
|
||||
{
|
||||
auto ddl = add_columns_ddl(this, table_name, info_vec);
|
||||
auto ddl = add_columns_ddl(table_name, info_vec);
|
||||
if (ddl.empty())
|
||||
return false;
|
||||
|
||||
@ -503,3 +503,108 @@ GncDbiSqlConnection::table_manage_backup (const std::string& table_name,
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Perform a specified SQL operation on every table in a
|
||||
* database. Possible operations are:
|
||||
* * drop: to DROP all tables from the database
|
||||
* * empty: to DELETE all records from each table in the database.
|
||||
* * backup: Rename every table from "name" to "name_back"
|
||||
* * drop_backup: DROP the backup tables.
|
||||
* * rollback: DROP the new table "name" and rename "name_back" to
|
||||
* "name", restoring the database to its previous state.
|
||||
*
|
||||
* The intent of the last two is to be able to move an existing table
|
||||
* aside, query its contents with a transformation (in 2.4.x this is
|
||||
* already done as the contents are loaded completely when a Qof
|
||||
* session is started), save them to a new table according to a new
|
||||
* database format, and finally drop the backup table; if there's an
|
||||
* error during the process, rollback allows returning the table to
|
||||
* its original state.
|
||||
*
|
||||
* @param sql_conn: The sql connection (via dbi) to which the
|
||||
* transactions will be sent
|
||||
* @param tables: GList of tables to operate on.
|
||||
* @param op: The operation to perform.
|
||||
* @return Success (TRUE) or failure.
|
||||
*/
|
||||
|
||||
bool
|
||||
GncDbiSqlConnection::table_operation(const std::vector<std::string>& table_names,
|
||||
TableOpType op) noexcept
|
||||
{
|
||||
const char* dbname = dbi_conn_get_option (m_conn, "dbname");
|
||||
std::string lock_table{m_lock_table};
|
||||
g_return_val_if_fail (!table_names.empty(), FALSE);
|
||||
bool retval{true};
|
||||
for (auto table : table_names)
|
||||
{
|
||||
dbi_result result;
|
||||
/* Ignore the lock table */
|
||||
if (table == lock_table)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
do
|
||||
{
|
||||
init_error();
|
||||
switch (op)
|
||||
{
|
||||
case rollback:
|
||||
{
|
||||
auto all_tables = m_provider->get_table_list(m_conn, dbname);
|
||||
if (std::find(all_tables.begin(),
|
||||
all_tables.end(), table) != all_tables.end())
|
||||
{
|
||||
result = dbi_conn_queryf (m_conn, "DROP TABLE %s",
|
||||
table.c_str());
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
case backup:
|
||||
case drop_backup:
|
||||
result = table_manage_backup (table, op);
|
||||
break;
|
||||
case empty:
|
||||
result = dbi_conn_queryf (m_conn, "DELETE FROM TABLE %s",
|
||||
table.c_str());
|
||||
break;
|
||||
case drop:
|
||||
default:
|
||||
result = dbi_conn_queryf (m_conn, "DROP TABLE %s", table.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (m_retry);
|
||||
|
||||
if (result != nullptr)
|
||||
{
|
||||
if (dbi_result_free (result) < 0)
|
||||
{
|
||||
PERR ("Error in dbi_result_free() result\n");
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string
|
||||
GncDbiSqlConnection::add_columns_ddl(const std::string& table_name,
|
||||
const ColVec& info_vec) const noexcept
|
||||
{
|
||||
std::string ddl;
|
||||
|
||||
ddl += "ALTER TABLE " + table_name;
|
||||
for (auto const& info : info_vec)
|
||||
{
|
||||
if (info != *info_vec.begin())
|
||||
{
|
||||
ddl += ", ";
|
||||
}
|
||||
ddl += "ADD COLUMN ";
|
||||
m_provider->append_col_def (ddl, info);
|
||||
}
|
||||
return ddl;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user