[glom/sqlbuilder2] Use Gnome::Gda::SqlBuilder
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom/sqlbuilder2] Use Gnome::Gda::SqlBuilder
- Date: Sat, 27 Feb 2010 14:18:17 +0000 (UTC)
commit 27fea3531c4f16972ca9a302bdba8b6c7ba7319e
Author: Murray Cumming <murrayc murrayc com>
Date: Sat Feb 27 15:17:09 2010 +0100
Use Gnome::Gda::SqlBuilder
* several files: Use Gnome::Gda::SqlBuilder to simplify query building and to
make it safer.
Much of this work was actually by Johannes Schmid for Openismus.
ChangeLog | 8 +
glom/base_db.cc | 609 +++++++++++++-------
glom/base_db.h | 34 +-
glom/base_db_table_data.cc | 30 +-
glom/base_db_table_data.h | 2 +-
glom/glom_privs.cc | 50 ++-
glom/libglom/connectionpool_backends/sqlite.cc | 32 +-
glom/libglom/python_embed/py_glom_record.cc | 38 +-
glom/libglom/python_embed/py_glom_related.cc | 13 +-
glom/libglom/python_embed/py_glom_relatedrecord.cc | 184 +++---
glom/libglom/python_embed/py_glom_relatedrecord.h | 4 +-
glom/mode_data/box_data_calendar_related.cc | 18 +-
glom/mode_data/box_data_portal.cc | 18 +-
glom/mode_design/dialog_database_preferences.cc | 39 +-
glom/mode_design/fields/box_db_table_definition.cc | 26 +-
glom/report_builder.cc | 4 +-
glom/utility_widgets/db_adddel/db_adddel.cc | 5 -
.../utility_widgets/db_adddel/glom_db_treemodel.cc | 14 +-
18 files changed, 712 insertions(+), 416 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d589430..02dad9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2010-02-27 Murray Cumming <murrayc murrayc com>
+ Use Gnome::Gda::SqlBuilder
+
+ * several files: Use Gnome::Gda::SqlBuilder to simplify query building and to
+ make it safer.
+ Much of this work was actually by Johannes Schmid for Openismus.
+
+2010-02-27 Murray Cumming <murrayc murrayc com>
+
Increase required version of libgdamm.
* configure.ac: Increase libgdamm dependency to the last one that doesn't
diff --git a/glom/base_db.cc b/glom/base_db.cc
index eafcaf2..7e7d421 100644
--- a/glom/base_db.cc
+++ b/glom/base_db.cc
@@ -212,54 +212,108 @@ Glib::RefPtr<Gnome::Gda::DataModel> Base_DB::query_execute_select(const Glib::us
const App_Glom* app = App_Glom::get_application();
if(stmt && app && app->get_show_sql_debug())
{
+ const std::string full_query = sqlbuilder_get_full_query(gda_connection, strQuery, params);
+ std::cout << "Debug: Base_DB::query_execute_select(): " << full_query << std::endl;
+ }
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
- {
- const Glib::ustring full_query = stmt->to_sql(params);
- std::cout << "Debug: Base_DB::query_execute_select(): " << full_query << std::endl;
- }
- catch(const Glib::Exception& ex)
- {
- std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
- }
+ try
+ {
+ result = gda_connection->statement_execute_select(stmt, params);
+ }
+ catch(const Gnome::Gda::ConnectionError& ex)
+ {
+ std::cout << "debug: Base_DB::query_execute_select(): ConnectionError: exception from statement_execute_select(): " << ex.what() << std::endl;
+ }
+ catch(const Gnome::Gda::ServerProviderError& ex)
+ {
+ std::cout << "debug: Base_DB::query_execute_select(): ServerProviderError exception from statement_execute_select(): code=" << ex.code() << ", message=" << ex.what() << std::endl;
+ }
+ catch(const Glib::Error& ex)
+ {
+ std::cout << "debug: Base_DB::query_execute_select(): Error exception from statement_execute_select(): " << ex.what() << std::endl;
+ }
#else
- const Glib::ustring full_query = stmt->to_sql(params, ex);
- std::cout << "Debug: Base_DB::query_execute_select(): " << full_query << std::endl;
- if (ex.get())
- std::cout << "Debug: query string could not be converted to std::cout: " << ex->what() << std::endl;
+ result = gda_connection->statement_execute_select(stmt, params, ex);
+ if(ex.get())
+ std::cout << "debug: Base_DB::query_execute_select(): Glib::Error from statement_execute_select(): " << ex->what() << std::endl;
+#endif //GLIBMM_EXCEPTIONS_ENABLED
+ if(!result)
+ {
+ const std::string full_query = sqlbuilder_get_full_query(gda_connection, strQuery, params);
+ std::cerr << "Glom Base_DB::query_execute_select(): Error while executing SQL" << std::endl <<
+ " " << full_query << std::endl;
+ handle_error();
+ }
+
+ return result;
+}
+
+//static:
+Glib::RefPtr<Gnome::Gda::DataModel> Base_DB::query_execute_select(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params)
+{
+ Glib::RefPtr<Gnome::Gda::DataModel> result;
+
+ //TODO: BusyCursor busy_cursor(get_app_window());
+
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ sharedptr<SharedConnection> sharedconnection = connect_to_server();
+#else
+ std::auto_ptr<ExceptionConnection> error;
+ sharedptr<SharedConnection> sharedconnection = connect_to_server(0, error);
+ if(error.get())
+ {
+ g_warning("Base_DB::query_execute_select() failed (query was: %s): %s", strQuery.c_str(), error->what());
+ // TODO: Rethrow?
+ }
#endif
+ if(!sharedconnection)
+ {
+ std::cerr << "Base_DB::query_execute_select(): No connection yet." << std::endl;
+ return result;
}
+ Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
+ //Debug output:
+ const App_Glom* app = App_Glom::get_application();
+ if(app && app->get_show_sql_debug())
+ {
+ const std::string full_query = sqlbuilder_get_full_query(builder, params);
+ std::cout << "Debug: Base_DB::query_execute_select(): " << full_query << std::endl;
+ }
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
- result = gda_connection->statement_execute_select(stmt, params);
+ result = gda_connection->statement_execute_select_builder(builder, params);
}
catch(const Gnome::Gda::ConnectionError& ex)
{
- std::cout << "debug: Base_DB::query_execute_select(): ConnectionError: exception from statement_execute_select(): " << ex.what() << std::endl;
+ std::cerr << "debug: Base_DB::query_execute_select(): ConnectionError: exception from statement_execute_select_builder(): " << ex.what() << std::endl;
}
catch(const Gnome::Gda::ServerProviderError& ex)
{
- std::cout << "debug: Base_DB::query_execute_select(): ServerProviderError: exception from statement_execute_select(): code=" << ex.code() << "message=" << ex.what() << std::endl;
+ std::cerr << "debug: Base_DB::query_execute_select(): ServerProviderError: exception from statement_execute_select_builder(): code=" << ex.code() << "message=" << ex.what() << std::endl;
}
catch(const Glib::Error& ex)
{
- std::cout << "debug: Base_DB::query_execute_select(): Error: exception from statement_execute_select(): " << ex.what() << std::endl;
+ std::cerr << "debug: Base_DB::query_execute_select(): Error: exception from statement_execute_select_builder(): " << ex.what() << std::endl;
}
#else
- result = gda_connection->statement_execute_select(stmt, params, ex);
+ result = gda_connection->statement_execute_select_builder(builder, params, ex);
if(ex.get())
- std::cout << "debug: Base_DB::query_execute_select(): Glib::Error from statement_execute_select(): " << ex->what() << std::endl;
+ std::cerr << "debug: Base_DB::query_execute_select(): Glib::Error from statement_execute_select_builder(): " << ex->what() << std::endl;
#endif //GLIBMM_EXCEPTIONS_ENABLED
if(!result)
{
- std::cerr << "Glom Base_DB::query_execute_select(): Error while executing SQL" << std::endl <<
- " " << strQuery << std::endl;
+ const std::string full_query = sqlbuilder_get_full_query(builder, params);
+ std::cerr << "Glom Base_DB::query_execute_select(): Error while executing SQL: "
+ << std::endl << " " << full_query << std::endl << std::endl;
handle_error();
}
@@ -315,24 +369,8 @@ bool Base_DB::query_execute(const Glib::ustring& strQuery,
const App_Glom* app = App_Glom::get_application();
if(stmt && app && app->get_show_sql_debug())
{
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
- {
- //TODO: full_query still seems to contain ## parameter names,
- //though it works for our SELECT queries in query_execute_select():
- const Glib::ustring full_query = stmt->to_sql(params);
- std::cerr << "Debug: Base_DB::query_execute(): " << full_query << std::endl;
- }
- catch(const Glib::Exception& ex)
- {
- std::cerr << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
- }
-#else
- const Glib::ustring full_query = stmt->to_sql(params, sql_error);
+ const std::string full_query = sqlbuilder_get_full_query(gda_connection, strQuery, params);
std::cerr << "Debug: Base_DB::query_execute(): " << full_query << std::endl;
- if (sql_error.get())
- std::cerr << "Debug: query string could not be converted to std::cout: " << sql_error->what() << std::endl;
-#endif
}
@@ -345,7 +383,7 @@ bool Base_DB::query_execute(const Glib::ustring& strQuery,
catch(const Glib::Error& error)
{
std::cerr << "BaseDB::query_execute: ConnectionError: " << error.what() << std::endl;
- const Glib::ustring full_query = stmt->to_sql(params);
+ const std::string full_query = sqlbuilder_get_full_query(gda_connection, strQuery, params);
std::cerr << " full_query: " << full_query << std::endl;
return false;
}
@@ -355,7 +393,66 @@ bool Base_DB::query_execute(const Glib::ustring& strQuery,
if(exec_error.get())
{
std::cerr << "BaseDB::query_execute: ConnectionError: " << exec_error->what() << std::endl;
- const Glib::ustring full_query = stmt->to_sql(params, exec_error);
+ const std::string full_query = sqlbuilder_get_full_query(gda_connection, stmt, params);
+ std::cerr << " full_query: " << full_query << std::endl;
+ return false;
+ }
+#endif
+ return (exec_retval >= 0);
+}
+
+//static:
+bool Base_DB::query_execute(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params)
+{
+ #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ sharedptr<SharedConnection> sharedconnection = connect_to_server();
+#else
+ std::auto_ptr<ExceptionConnection> error;
+ sharedptr<SharedConnection> sharedconnection = connect_to_server(0, error);
+ if(error.get())
+ {
+ g_warning("Base_DB::query_execute() failed (query was: %s): %s", strQuery.c_str(), error->what());
+ // TODO: Rethrow?
+ }
+#endif
+ if(!sharedconnection)
+ {
+ std::cerr << "Base_DB::query_execute(): No connection yet." << std::endl;
+ return false;
+ }
+
+ Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
+
+ //Debug output:
+ const App_Glom* app = App_Glom::get_application();
+ if(app && app->get_show_sql_debug())
+ {
+ const std::string full_query = sqlbuilder_get_full_query(builder, params);
+ std::cerr << "Debug: Base_DB::query_execute(): " << full_query << std::endl;
+ }
+
+
+ int exec_retval = -1;
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ try
+ {
+ exec_retval = gda_connection->statement_execute_non_select_builder(builder, params);
+ }
+ catch(const Glib::Error& error)
+ {
+ std::cerr << "BaseDB::query_execute: ConnectionError: " << error.what() << std::endl;
+ const std::string full_query = sqlbuilder_get_full_query(builder, params);
+ std::cerr << " full_query: " << full_query << std::endl;
+ return false;
+ }
+#else
+ std::auto_ptr<Glib::Error> exec_error;
+ exec_retval = gda_connection->statement_execute_non_select_builder(builder, params, exec_error);
+ if(exec_error.get())
+ {
+ std::cerr << "BaseDB::query_execute: ConnectionError: " << exec_error->what() << std::endl;
+ const std::string full_query = sqlbuilder_get_full_query(builder, params);
std::cerr << " full_query: " << full_query << std::endl;
return false;
}
@@ -892,25 +989,34 @@ Gnome::Gda::Value Base_DB::auto_increment_insert_first_if_necessary(const Glib::
//This should not happen:
std::cerr << "Glom: Base_DB::auto_increment_insert_first_if_necessary(): The current user may not edit the autoincrements table. Any user who has create rights for a table should have edit rights to the autoincrements table." << std::endl;
}
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder("table_name", table_name);
- params->add_holder("field_name", field_name);
-
- const Glib::ustring sql_query = "SELECT \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\".\"next_value\" FROM \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\""
- " WHERE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME "\" = ##table_name::gchararray AND "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME "\" = ##field_name::gchararray";
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query, params);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("next_value", GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->select_add_target(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_AND,
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME),
+ builder->add_expr(table_name)),
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME),
+ builder->add_expr(field_name))));
+
+ const Glib::RefPtr<const Gnome::Gda::DataModel> datamodel = query_execute_select(builder);
if(!datamodel || (datamodel->get_n_rows() == 0))
{
//Start with zero:
+ builder.reset();
//Insert the row if it's not there.
- const Glib::ustring sql_query = "INSERT INTO \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\" ("
- GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME ", " GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME ", " GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE
- ") VALUES (##table_name::gchararray, ##field_name::gchararray, 0)";
+ builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_INSERT);
+ builder->set_table(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->add_field_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME, table_name);
+ builder->add_field_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME, field_name);
+ builder->add_field_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE, 0);
- const bool test = query_execute(sql_query, params);
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::auto_increment_insert_first_if_necessary(): INSERT of new row failed." << std::endl;
@@ -944,8 +1050,13 @@ void Base_DB::recalculate_next_auto_increment_value(const Glib::ustring& table_n
auto_increment_insert_first_if_necessary(table_name, field_name);
//Get the max key value in the database:
- const Glib::ustring sql_query = "SELECT MAX(\"" + table_name + "\".\"" + field_name + "\") FROM \"" + table_name + "\"";
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ std::list<guint> args;
+ args.push_back(builder->add_id(table_name + "." + field_name));
+ builder->add_field_id(builder->add_function("MAX", args));
+ builder->select_add_target(table_name);
+
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(builder);
if(datamodel && datamodel->get_n_rows() && datamodel->get_n_columns())
{
//Increment it:
@@ -960,12 +1071,20 @@ void Base_DB::recalculate_next_auto_increment_value(const Glib::ustring& table_n
//Set it in the glom system table:
const Gnome::Gda::Value next_value = Conversions::parse_value(num_max);
- const Glib::ustring sql_query = "UPDATE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\" SET "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE "\" = " + next_value.to_string() + //TODO: Don't use to_string().
- " WHERE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME "\" = '" + table_name + "' AND "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME "\" = '" + field_name + "'";
- const bool test = query_execute(sql_query);
+ builder.reset();
+ builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->add_field_value_as_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE, next_value);
+ builder->set_where(builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_AND,
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME),
+ builder->add_expr(table_name)),
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME),
+ builder->add_expr(field_name))));
+
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::recalculate_next_auto_increment_value(): UPDATE failed." << std::endl;
}
@@ -982,16 +1101,18 @@ Gnome::Gda::Value Base_DB::get_next_auto_increment_value(const Glib::ustring& ta
//Increment the next_value:
++num_result;
const Gnome::Gda::Value next_value = Conversions::parse_value(num_result);
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder("table_name", table_name);
- params->add_holder("field_name", field_name);
- params->add_holder("next_value", next_value);
- const Glib::ustring sql_query = "UPDATE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\" SET "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE "\" = ##next_value::gchararray"
- " WHERE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME "\" = ##table_name::gchararray AND "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME "\" = ##field_name::gchararray";
-
- const bool test = query_execute(sql_query, params);
+
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->add_field_value_as_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE, next_value);
+ builder->set_where(builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_AND,
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME),
+ builder->add_expr(table_name)),
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME),
+ builder->add_expr(field_name))));
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::get_next_auto_increment_value(): Increment failed." << std::endl;
@@ -1012,27 +1133,34 @@ SystemPrefs Base_DB::get_database_preferences() const
const bool optional_org_logo = get_field_exists_in_database(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME, GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO);
- const Glib::ustring sql_query = "SELECT "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_NAME "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_NAME "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2 "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY "\", "
- "\"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE "\""
- + Glib::ustring(optional_org_logo ? ", \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO "\"" : "") +
- " FROM \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\"";
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_NAME, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_NAME, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+
+ if(optional_org_logo)
+ {
+ builder->select_add_field(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO, GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ }
+
+ builder->select_add_target(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
int attempts = 0;
while(attempts < 2)
{
bool succeeded = true;
- #ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
+ std::string full_query = sqlbuilder_get_full_query(builder);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(builder);
+ if(datamodel && (datamodel->get_n_rows() != 0))
{
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
- if(datamodel && (datamodel->get_n_rows() != 0))
+ #ifdef GLIBMM_EXCEPTIONS_ENABLED
+ try
{
result.m_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(0, 0));
result.m_org_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(1, 0));
@@ -1047,24 +1175,18 @@ SystemPrefs Base_DB::get_database_preferences() const
if(optional_org_logo)
result.m_org_logo = datamodel->get_value_at(8, 0);
}
- else
+ catch(const Glib::Exception& ex)
+ {
+ std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
succeeded = false;
- }
- catch(const Glib::Exception& ex)
- {
- std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
- succeeded = false;
- }
- catch(const std::exception& ex)
- {
- std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
- succeeded = false;
- }
- #else // GLIBMM_EXCEPTIONS_ENABLED
- std::auto_ptr<Glib::Error> error;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
- if(datamodel && (datamodel->get_n_rows() != 0))
- {
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
+ succeeded = false;
+ }
+ #else // GLIBMM_EXCEPTIONS_ENABLED
+ std::auto_ptr<Glib::Error> error;
result.m_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(0, 0, error));
result.m_org_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(1, 0, error));
result.m_org_address_street = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(2, 0, error));
@@ -1077,16 +1199,17 @@ SystemPrefs Base_DB::get_database_preferences() const
//We need to be more clever about these column indexes if we add more new fields:
if(optional_org_logo)
result.m_org_logo = datamodel->get_value_at(8, 0, error);
+
+ if(error.get())
+ {
+ std::cerr << "Error: " << error->what() << std::endl;
+ succeeded = false;
+ }
+ #endif
}
else
succeeded = false;
- if (error.get())
- {
- std::cerr << "Error: " << error->what() << std::endl;
- succeeded = false;
- }
- #endif
//Return the result, or try again:
if(succeeded)
return result;
@@ -1121,7 +1244,10 @@ bool Base_DB::add_standard_tables() const
if(test)
{
//Add the single record:
- const bool test = query_execute("INSERT INTO \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\" (\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ID "\") VALUES (1)");
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_INSERT);
+ builder->set_table(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ID, 1);
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::add_standard_tables(): INSERT failed." << std::endl;
@@ -1129,7 +1255,13 @@ bool Base_DB::add_standard_tables() const
const Glib::ustring system_name = get_document()->get_database_title();
if(!system_name.empty())
{
- const bool test = query_execute("UPDATE \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\" SET " "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_NAME "\" = '" + system_name + "' WHERE \"" GLOM_STANDARD_TABLE_PREFS_FIELD_ID "\" = 1");
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_NAME, system_name);
+ builder->set_where(builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_PREFS_FIELD_ID),
+ builder->add_expr(1)));
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::add_standard_tables(): UPDATE failed." << std::endl;
}
@@ -1290,37 +1422,26 @@ void Base_DB::set_database_preferences(const SystemPrefs& prefs)
if(get_userlevel() == AppState::USERLEVEL_DEVELOPER)
add_standard_tables();
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder("name", prefs.m_name);
- params->add_holder("street", prefs.m_org_address_street);
- params->add_holder("street2", prefs.m_org_address_street2);
- params->add_holder("town", prefs.m_org_address_town);
- params->add_holder("county", prefs.m_org_address_county);
- params->add_holder("country", prefs.m_org_address_country);
- params->add_holder("postcode", prefs.m_org_address_postcode);
-
//The logo field was introduced in a later version of Glom.
//If the user is not in developer mode then the new field has not yet been added:
- Glib::ustring optional_part_logo;
+
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_NAME, prefs.m_name);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET, prefs.m_org_address_street);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2, prefs.m_org_address_street2);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN, prefs.m_org_address_town);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY, prefs.m_org_address_county);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY, prefs.m_org_address_country);
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE, prefs.m_org_address_postcode);
if(get_field_exists_in_database(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME, GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO))
{
- params->add_holder("org_logo", prefs.m_org_logo);
- optional_part_logo = "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO "\" = ##org_logo::GDA_TYPE_BINARY, ";
+ builder->add_field_value(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO, prefs.m_org_logo);
}
- const Glib::ustring sql_query = "UPDATE \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\" SET "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_NAME "\" = ##name::gchararray, "
- + optional_part_logo +
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET "\" = ##street::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2 "\" = ##street2::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN "\" = ##town::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY "\" = ##county::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY "\" = ##country::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE "\" = ##postcode::gchararray"
- " WHERE \"" GLOM_STANDARD_TABLE_PREFS_FIELD_ID "\" = 1";
-
- bool test = false;
- test = query_execute(sql_query, params);
-
+ builder->set_where(builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_PREFS_FIELD_ID),
+ builder->add_expr(1)));
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Base_DB::set_database_preferences(): UPDATE failed." << std::endl;
@@ -1746,18 +1867,12 @@ bool Base_DB::insert_example_data(const Glib::ustring& table_name) const
//std::cout << "DEBUG: row_data size = " << row_data.size() << ", (fields size= " << vec_fields.size() << " )" << std::endl;
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
ParameterNameGenerator generator;
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_INSERT);
+ builder->set_table(table_name);
+
for(unsigned int i = 0; i < row_data.size(); ++i) //TODO_Performance: Avoid calling size() so much.
{
- //std::cout << " DEBUG: i=" << i << ", row_data.size()=" << row_data.size() << std::endl;
-
- if(i > 0)
- {
- strVals += ", ";
- strNames += ", ";
- }
-
sharedptr<Field> field = vec_fields[i];
if(!field)
{
@@ -1765,35 +1880,21 @@ bool Base_DB::insert_example_data(const Glib::ustring& table_name) const
break;
}
- strNames += field->get_name();
-
- Gnome::Gda::Value value = row_data[i];
- //std::cout << " DEBUG: example: field=" << field->get_name() << ", value=" << value.to_string() << std::endl;
-
- //Add a SQL parameter for the value:
- guint id = 0;
- const Field::glom_field_type glom_type = field->get_glom_type();
- Glib::RefPtr<Gnome::Gda::Holder> holder =
- Gnome::Gda::Holder::create( Field::get_gda_type_for_glom_type(glom_type),
- generator.get_next_name(id));
-
- holder->set_not_null(false);
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- holder->set_value_as_value(value);
-#else
- std::auto_ptr<Glib::Error> holder_error;
- holder->set_value_as_value(value, holder_error);
-#endif
- params->add_holder(holder);
-
- strVals += "##" + generator.get_name_from_id(id) + "::" + vec_fields[i]->get_gda_type_name();
+ const Gnome::Gda::Value& value = row_data[i];
+ if(!value.is_null()) //TODO: Remove this check when libgda allows this.
+ {
+ /*
+ std::cout << "debug: field=" << field->get_name() << ", value=" << value.to_string() << std::endl;
+ if(value.get_value_type() == GDA_TYPE_NULL)
+ std::cout << " (GDA_TYPE_NULL)" << std::endl;
+ else
+ std::cout << " value.get_value_type()=" << value.get_value_type() << std::endl;
+ */
+ builder->add_field_value_as_value(field->get_name(), value);
+ }
}
-
- //Create and parse the SQL query:
- //After this, the Parser will know how many SQL parameters there are in
- //the query, and allow us to set their values.
- const Glib::ustring strQuery = "INSERT INTO \"" + table_name + "\" (" + strNames + ") VALUES (" + strVals + ")";
- insert_succeeded = query_execute(strQuery, params);
+
+ insert_succeeded = query_execute(builder);
if(!insert_succeeded)
break;
}
@@ -2445,8 +2546,11 @@ void Base_DB::calculate_field_in_all_records(const Glib::ustring& table_name, co
{
//Get primary key values for every record:
- const Glib::ustring query = "SELECT \"" + table_name + "\".\"" + primary_key->get_name() + "\" FROM \"" + table_name + "\"";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(query);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(primary_key->get_name(), table_name);
+ builder->select_add_target(table_name);
+
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(!data_model || !data_model->get_n_rows() || !data_model->get_n_columns())
{
//HandleError();
@@ -2750,19 +2854,19 @@ bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& layoutfield
const Glib::ustring field_name = field_in_record.m_field->get_name();
if(!field_name.empty()) //This should not happen.
{
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder(field_in_record.m_field->get_holder(field_value));
- params->add_holder(field_in_record.m_key->get_holder(field_in_record.m_key_value));
-
- Glib::ustring strQuery = "UPDATE \"" + field_in_record.m_table_name + "\"";
- strQuery += " SET \"" + field_in_record.m_field->get_name() + "\" = " + field_in_record.m_field->get_gda_holder_string();
- strQuery += " WHERE \"" + field_in_record.m_key->get_name() + "\" = " + field_in_record.m_key->get_gda_holder_string();
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(field_in_record.m_table_name);
+ builder->add_field_value_as_value(field_in_record.m_field->get_name(), field_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(field_in_record.m_key->get_name()),
+ builder->add_expr_as_value(field_in_record.m_key_value)));
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try //TODO: The exceptions are probably already handled by query_execute(0.
#endif
{
- const bool test = query_execute(strQuery, params); //TODO: Respond to failure.
+ const bool test = query_execute(builder); //TODO: Respond to failure.
if(!test)
{
std::cerr << "Box_Data::set_field_value_in_database(): UPDATE failed." << std::endl;
@@ -3081,10 +3185,6 @@ void Base_DB::do_lookups(const LayoutFieldInRecord& field_in_record, const Gtk::
//Add it to the database (even if it is not shown in the view)
set_field_value_in_database(field_in_record_to_set, row, value_converted); //Also does dependent lookups/recalcs.
- //Glib::ustring strQuery = "UPDATE \"" + m_table_name + "\"";
- //strQuery += " SET " + field_lookup.get_name() + " = " + field_lookup.sql(value);
- //strQuery += " WHERE " + primary_key.get_name() + " = " + primary_key.sql(primary_key_value);
- //query_execute(strQuery); //TODO: Handle errors
//TODO: Handle lookups triggered by these fields (recursively)? TODO: Check for infinitely looping lookups.
}
@@ -3147,13 +3247,17 @@ Gnome::Gda::Value Base_DB::get_lookup_value(const Glib::ustring& /* table_name *
{
//Convert the value, in case the from and to fields have different types:
const Gnome::Gda::Value value_to_key_field = Conversions::convert_value(key_value, to_key_field->get_glom_type());
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder("key", value_to_key_field);
-
- Glib::ustring strQuery = "SELECT \"" + relationship->get_to_table() + "\".\"" + source_field->get_name() + "\" FROM \"" + relationship->get_to_table() + "\"";
- strQuery += " WHERE \"" + to_key_field->get_name() + "\" = ##key::" + to_key_field->get_gda_type_name();
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery, params);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(source_field->get_name(), relationship->get_to_table());
+ builder->select_add_target(relationship->get_to_table());
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(to_key_field->get_name()), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(value_to_key_field)));
+
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model && data_model->get_n_rows())
{
//There should be only 1 row. Well, there could be more but we will ignore them.
@@ -3179,15 +3283,16 @@ bool Base_DB::get_field_value_is_unique(const Glib::ustring& table_name, const s
const Glib::ustring table_name_used = field->get_table_used(table_name);
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- sharedptr<const Field> glom_field = field->get_full_field_details();
- if(glom_field)
- params->add_holder(glom_field->get_holder(value));
-
- const Glib::ustring strQuery = "SELECT \"" + table_name_used + "\".\"" + field->get_name() + "\" FROM \"" + table_name_used + "\""
- " WHERE \"" + field->get_name() + "\" = " + glom_field->get_gda_holder_string();
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(field->get_name(), table_name_used);
+ builder->select_add_target(table_name_used);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(field->get_name()), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(value)));
- Glib::RefPtr<const Gnome::Gda::DataModel> data_model = query_execute_select(strQuery, params);
+ Glib::RefPtr<const Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model)
{
//std::cout << "debug: Base_DB::get_field_value_is_unique(): table_name=" << table_name << ", field name=" << field->get_name() << ", value=" << value.to_string() << ", rows count=" << data_model->get_n_rows() << std::endl;
@@ -3409,6 +3514,13 @@ int Base_DB::count_rows_returned_by(const Glib::ustring& sql_query)
//Note that the alias is just because the SQL syntax requires it - we get an error if we don't use it.
//Be careful not to include ORDER BY clauses in this, because that would make it unnecessarily slow:
const Glib::ustring query_count = "SELECT COUNT (*) FROM (" + sql_query + ") AS glomarbitraryalias";
+
+ /* TODO: Use SqlBuilder when we discover how to use a sub-query, or when this function can take a Sqlbuilder.
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->add_function("count", builder->add_id("*")); //TODO: Is * allowed here?
+ builder->select_add_target(m_found_set.m_table_name);
+ */
const App_Glom* app = App_Glom::get_application();
if(app && app->get_show_sql_debug())
@@ -3738,4 +3850,101 @@ Glib::ustring Base_DB::get_active_layout_platform(Document* document)
}
+std::string Base_DB::sqlbuilder_get_full_query(
+ const Glib::RefPtr<Gnome::Gda::Connection>& connection,
+ const Glib::ustring& query,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params)
+{
+ Glib::ustring result = "glom_query_not_parsed";
+
+ try
+ {
+ Glib::RefPtr<Gnome::Gda::SqlParser> parser = connection->create_parser();
+ if(parser)
+ {
+ Glib::RefPtr<Gnome::Gda::Statement> stmt = parser->parse_string(query);
+ if(stmt)
+ result = stmt->to_sql(params);
+ }
+ }
+ catch(const Glib::Exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while parsing query: " << ex.what() << std::endl;
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while parsing query: " << ex.what() << std::endl;
+ }
+
+ //Convert to something that std::cout should be able to handle.
+ const Glib::ScopedPtr<char> buf(g_convert_with_fallback(
+ result.raw().data(), result.raw().size(),
+ "ISO-8859-1", "UTF-8",
+ (char*)"?",
+ 0, 0, 0));
+ return std::string(buf.get());
+}
+
+std::string Base_DB::sqlbuilder_get_full_query(
+ const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params)
+{
+ Glib::ustring result = "glom_query_not_parsed";
+
+ try
+ {
+ Glib::RefPtr<Gnome::Gda::Statement> stmt = builder->get_statement();
+ if(stmt)
+ result = stmt->to_sql(params);
+ }
+ catch(const Glib::Exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while getting query: " << ex.what() << std::endl;
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while getting query: " << ex.what() << std::endl;
+ }
+
+ //Convert to something that std::cout should be able to handle.
+ const Glib::ScopedPtr<char> buf(g_convert_with_fallback(
+ result.raw().data(), result.raw().size(),
+ "ISO-8859-1", "UTF-8",
+ (char*)"?",
+ 0, 0, 0));
+ return std::string(buf.get());
+}
+
+std::string Base_DB::sqlbuilder_get_full_query(
+ const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder)
+{
+ Glib::ustring result = "glom_query_not_parsed";
+
+ try
+ {
+ Glib::RefPtr<Gnome::Gda::Statement> stmt = builder->get_statement();
+ if(stmt)
+ result = stmt->to_sql();
+ }
+ catch(const Glib::Exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while getting query: " << ex.what() << std::endl;
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << "sqlbuilder_get_full_query(): exception while getting query: " << ex.what() << std::endl;
+ }
+
+ //Convert to something that std::cout should be able to handle.
+ const Glib::ScopedPtr<char> buf(g_convert_with_fallback(
+ result.raw().data(), result.raw().size(),
+ "ISO-8859-1", "UTF-8",
+ (char*)"?",
+ 0, 0, 0));
+ return std::string(buf.get());
+}
+
+
+
+
} //namespace Glom
diff --git a/glom/base_db.h b/glom/base_db.h
index 6fce311..bfa0b08 100644
--- a/glom/base_db.h
+++ b/glom/base_db.h
@@ -36,6 +36,9 @@
#include <libglom/document/bakery/view/view.h>
#include <glom/bakery/busy_cursor.h>
+#include <libgdamm/set.h>
+#include <libgdamm/sqlbuilder.h>
+
namespace Glom
{
@@ -81,8 +84,12 @@ public:
/** Execute a SQL Select command, returning the result.
* This method handles any Gda exceptions caused by executing the command.
*/
- static Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(const Glib::ustring& strQuery,
- const Glib::RefPtr<Gnome::Gda::Set>& params = Glib::RefPtr<Gnome::Gda::Set>(0));
+ static Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(
+ const Glib::ustring& strQuery,
+ const Glib::RefPtr<Gnome::Gda::Set>& params = Glib::RefPtr<Gnome::Gda::Set>(0));
+ static Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(
+ const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params = Glib::RefPtr<const Gnome::Gda::Set>(0));
/** Execute a SQL non-select command, returning true if it succeeded.
@@ -90,9 +97,11 @@ public:
*/
static bool query_execute(const Glib::ustring& strQuery,
const Glib::RefPtr<Gnome::Gda::Set>& params = Glib::RefPtr<Gnome::Gda::Set>(0));
-
+ static bool query_execute(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params = Glib::RefPtr<const Gnome::Gda::Set>(0));
+
static int count_rows_returned_by(const Glib::ustring& sql_query);
-
+
#ifndef GLOM_ENABLE_CLIENT_ONLY
bool add_standard_groups();
bool add_standard_tables() const;
@@ -428,7 +437,24 @@ protected:
static void handle_error(const Glib::Exception& ex);
static void handle_error(const std::exception& ex); //TODO_port: This is probably useless now.
static bool handle_error();
+
+private:
+ /// Get the full query string suitable for use with std::cout.
+ static std::string sqlbuilder_get_full_query(
+ const Glib::RefPtr<Gnome::Gda::Connection>& connection,
+ const Glib::ustring& query,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params);
+
+ /// Get the full query string suitable for use with std::cout.
+ static std::string sqlbuilder_get_full_query(
+ const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+ const Glib::RefPtr<const Gnome::Gda::Set>& params);
+
+ /// Get the full query string suitable for use with std::cout.
+ static std::string sqlbuilder_get_full_query(
+ const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder);
+protected:
type_field_calcs m_FieldsCalculationInProgress; //Prevent circular calculations and recalculations.
};
diff --git a/glom/base_db_table_data.cc b/glom/base_db_table_data.cc
index be5ac82..c72a1ce 100644
--- a/glom/base_db_table_data.cc
+++ b/glom/base_db_table_data.cc
@@ -262,7 +262,7 @@ bool Base_DB_Table_Data::record_new(bool use_entered_data, const Gnome::Gda::Val
}
-bool Base_DB_Table_Data::get_related_record_exists(const sharedptr<const Relationship>& relationship, const sharedptr<const Field>& key_field, const Gnome::Gda::Value& key_value)
+bool Base_DB_Table_Data::get_related_record_exists(const sharedptr<const Relationship>& relationship, const Gnome::Gda::Value& key_value)
{
BusyCursor cursor(App_Glom::get_application());
@@ -277,9 +277,17 @@ bool Base_DB_Table_Data::get_related_record_exists(const sharedptr<const Relatio
const Glib::ustring to_field = relationship->get_to_field();
const Glib::ustring related_table = relationship->get_to_table();
- //TODO_Performance: Is this the best way to just find out whether there is one record that meets this criteria?
- const Glib::ustring query = "SELECT \"" + to_field + "\" FROM \"" + relationship->get_to_table() + "\" WHERE \"" + related_table + "\".\"" + to_field + "\" = " + key_field->sql(key_value);
- Glib::RefPtr<Gnome::Gda::DataModel> records = query_execute_select(query);
+ //TODO_Performance: Is this the best way to just find out whether there is one record that meets this criteria?
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(to_field, related_table);
+ builder->select_add_target(related_table);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(to_field), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(key_value)));
+
+ Glib::RefPtr<Gnome::Gda::DataModel> records = query_execute_select(builder);
if(!records)
handle_error();
else
@@ -300,7 +308,7 @@ bool Base_DB_Table_Data::add_related_record_for_field(const sharedptr<const Layo
{
Gnome::Gda::Value primary_key_value = primary_key_value_provided;
- const bool related_record_exists = get_related_record_exists(relationship, primary_key_field, primary_key_value);
+ const bool related_record_exists = get_related_record_exists(relationship, primary_key_value);
if(related_record_exists)
{
//No problem, the SQL command below will update this value in the related table.
@@ -413,6 +421,18 @@ bool Base_DB_Table_Data::add_related_record_for_field(const sharedptr<const Layo
params->add_holder(parent_primary_key_field->get_holder(parent_primary_key_value));
const Glib::ustring strQuery = "UPDATE \"" + relationship->get_from_table() + "\" SET \"" + relationship->get_from_field() + "\" = " + primary_key_field->get_gda_holder_string() +
" WHERE \"" + relationship->get_from_table() + "\".\"" + parent_primary_key_field->get_name() + "\" = " + parent_primary_key_field->get_gda_holder_string();
+
+ /* TODO: Use SqlBuilder when can know how to specify the related field properly in the condition:
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(relationship->get_from_table());
+ builder->add_field_value_as_value(relationship->get_from_field(), primary_key_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id("\"" + relationship->get_from_table() + "\".\"" + parent_primary_key_field->get_name() + "\""),
+ builder->add_expr(parent_primary_key_value)),
+ */
+
const bool test = query_execute(strQuery, params);
if(!test)
{
diff --git a/glom/base_db_table_data.h b/glom/base_db_table_data.h
index ce6882a..ea4f5cd 100644
--- a/glom/base_db_table_data.h
+++ b/glom/base_db_table_data.h
@@ -95,7 +95,7 @@ protected:
type_signal_record_changed m_signal_record_changed;
private:
- bool get_related_record_exists(const sharedptr<const Relationship>& relationship, const sharedptr<const Field>& key_field, const Gnome::Gda::Value& key_value);
+ bool get_related_record_exists(const sharedptr<const Relationship>& relationship, const Gnome::Gda::Value& key_value);
};
} //namespace Glom
diff --git a/glom/glom_privs.cc b/glom/glom_privs.cc
index 1c08d69..79b62e3 100644
--- a/glom/glom_privs.cc
+++ b/glom/glom_privs.cc
@@ -33,8 +33,12 @@ Privs::type_vec_strings Privs::get_database_groups()
{
type_vec_strings result;
- const Glib::ustring strQuery = "SELECT \"pg_group\".\"groname\" FROM \"pg_group\"";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("groname", "pg_group");
+ builder->select_add_target("pg_group");
+
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model)
{
const int rows_count = data_model->get_n_rows();
@@ -101,8 +105,12 @@ Privs::type_vec_strings Privs::get_database_users(const Glib::ustring& group_nam
if(group_name.empty())
{
//pg_shadow contains the users. pg_users is a view of pg_shadow without the password.
- const Glib::ustring strQuery = "SELECT \"pg_shadow\".\"usename\" FROM \"pg_shadow\"";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("usename", "pg_shadow");
+ builder->select_add_target("pg_shadow");
+
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model)
{
const int rows_count = data_model->get_n_rows();
@@ -121,8 +129,16 @@ Privs::type_vec_strings Privs::get_database_users(const Glib::ustring& group_nam
}
else
{
- const Glib::ustring strQuery = "SELECT \"pg_group\".\"groname\", \"pg_group\".\"grolist\" FROM \"pg_group\" WHERE \"pg_group\".\"groname\" = '" + group_name + "'";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("groname", "pg_group");
+ builder->select_add_field("grolist", "pg_group");
+ builder->select_add_target("pg_group");
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id("groname"), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(group_name)));
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model && data_model->get_n_rows())
{
const int rows_count = data_model->get_n_rows();
@@ -144,8 +160,15 @@ Privs::type_vec_strings Privs::get_database_users(const Glib::ustring& group_nam
for(type_vec_strings::const_iterator iter = vecUserIds.begin(); iter != vecUserIds.end(); ++iter)
{
//TODO_Performance: Can we do this in one SQL SELECT?
- const Glib::ustring strQuery = "SELECT \"pg_user\".\"usename\" FROM \"pg_user\" WHERE \"pg_user\".\"usesysid\" = '" + *iter + "'";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("usename", "pg_user");
+ builder->select_add_target("pg_user");
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id("usesysid"), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(*iter)));
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model)
{
#ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -253,8 +276,15 @@ Privileges Privs::get_table_privileges(const Glib::ustring& group_name, const Gl
}
//Get the permissions:
- Glib::ustring strQuery = "SELECT \"pg_class\".\"relacl\" FROM \"pg_class\" WHERE \"pg_class\".\"relname\" = '" + table_name + "'";
- Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(strQuery);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field("relacl", "pg_class");
+ builder->select_add_target("pg_class");
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id("relname"), //TODO: It would be nice to specify the table here too.
+ builder->add_expr(table_name)));
+ Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute_select(builder);
if(data_model && data_model->get_n_rows())
{
#ifdef GLIBMM_EXCEPTIONS_ENABLED
diff --git a/glom/libglom/connectionpool_backends/sqlite.cc b/glom/libglom/connectionpool_backends/sqlite.cc
index 01df7bc..2b3e5ac 100644
--- a/glom/libglom/connectionpool_backends/sqlite.cc
+++ b/glom/libglom/connectionpool_backends/sqlite.cc
@@ -226,21 +226,21 @@ bool Sqlite::recreate_table(const Glib::RefPtr<Gnome::Gda::Connection>& connecti
{
case Field::TYPE_TEXT:
if(column->gtype == G_TYPE_BOOLEAN)
- trans_fields += Glib::ustring("(CASE WHEN ") + column->column_name + " = 1 THEN 'true' "
- "WHEN " + column->column_name + " = 0 THEN 'false' "
- "WHEN " + column->column_name + " IS NULL THEN 'false' END)";
+ trans_fields += Glib::ustring("(CASE WHEN \"") + column->column_name + "\" = 1 THEN 'true' "
+ "WHEN \"" + column->column_name + "\" = 0 THEN 'false' "
+ "WHEN \"" + column->column_name + "\" IS NULL THEN 'false' END)";
else if(column->gtype == GDA_TYPE_BLOB)
trans_fields += "''";
else
// Make sure we don't insert NULL strings, as we ignore that concept in Glom.
- trans_fields += Glib::ustring("(CASE WHEN ") + column->column_name + " IS NULL THEN '' "
- "WHEN " + column->column_name + " IS NOT NULL THEN " + column->column_name + " END)";
+ trans_fields += Glib::ustring("(CASE WHEN \"") + column->column_name + "\" IS NULL THEN '' "
+ "WHEN \"" + column->column_name + "\" IS NOT NULL THEN \"" + column->column_name + "\" END)";
break;
case Field::TYPE_NUMERIC:
if(column->gtype == G_TYPE_BOOLEAN)
- trans_fields += Glib::ustring("(CASE WHEN ") + column->column_name + " = 0 THEN 0 "
- "WHEN " + column->column_name + " != 0 THEN 1 "
- "WHEN " + column->column_name + " IS NULL THEN 0 END)";
+ trans_fields += Glib::ustring("(CASE WHEN \"") + column->column_name + "\" = 0 THEN 0 "
+ "WHEN \"" + column->column_name + "\" != 0 THEN 1 "
+ "WHEN \"" + column->column_name + "\" IS NULL THEN 0 END)";
else if(column->gtype == GDA_TYPE_BLOB || column->gtype == G_TYPE_DATE || column->gtype == GDA_TYPE_TIME)
trans_fields += '0';
else
@@ -248,13 +248,13 @@ bool Sqlite::recreate_table(const Glib::RefPtr<Gnome::Gda::Connection>& connecti
break;
case Field::TYPE_BOOLEAN:
if(column->gtype == G_TYPE_STRING)
- trans_fields += Glib::ustring("(CASE WHEN ") + column->column_name + " = 'true' THEN 1 "
- "WHEN " + column->column_name + " = 'false' THEN 0 "
- "WHEN " + column->column_name + " IS NULL THEN 0 END)";
+ trans_fields += Glib::ustring("(CASE WHEN \"") + column->column_name + "\" = 'true' THEN 1 "
+ "WHEN \"" + column->column_name + "\" = 'false' THEN 0 "
+ "WHEN \"" + column->column_name + "\" IS NULL THEN 0 END)";
else if(column->gtype == G_TYPE_DOUBLE)
- trans_fields += Glib::ustring("(CASE WHEN ") + column->column_name + " = 0 THEN 0 "
- "WHEN " + column->column_name + " != 0 THEN 1 "
- "WHEN " + column->column_name + " IS NULL THEN 0 END)";
+ trans_fields += Glib::ustring("(CASE WHEN \"") + column->column_name + "\" = 0 THEN 0 "
+ "WHEN \"" + column->column_name + "\" != 0 THEN 1 "
+ "WHEN \"" + column->column_name + "\" IS NULL THEN 0 END)";
else if(column->gtype == G_TYPE_BOOLEAN)
trans_fields += column->column_name;
else
@@ -334,11 +334,11 @@ bool Sqlite::recreate_table(const Glib::RefPtr<Gnome::Gda::Connection>& connecti
if(perform_server_operation(connection->get_provider(), connection, operation, error))
{
- if(trans_fields.empty() || query_execute(connection, Glib::ustring("INSERT INTO ") + TEMPORARY_TABLE_NAME + " SELECT " + trans_fields + " FROM " + table_name, error))
+ if(trans_fields.empty() || query_execute(connection, Glib::ustring("INSERT INTO \"") + TEMPORARY_TABLE_NAME + "\" SELECT " + trans_fields + " FROM \"" + table_name + "\"", error))
{
if(query_execute(connection, "DROP TABLE " + table_name, error))
{
- if(query_execute(connection, Glib::ustring("ALTER TABLE ") + TEMPORARY_TABLE_NAME + " RENAME TO " + table_name, error))
+ if(query_execute(connection, Glib::ustring("ALTER TABLE \"") + TEMPORARY_TABLE_NAME + "\" RENAME TO \"" + table_name + "\"", error))
{
if(commit_transaction(connection, TRANSACTION_NAME, error))
{
diff --git a/glom/libglom/python_embed/py_glom_record.cc b/glom/libglom/python_embed/py_glom_record.cc
index a989659..f62c396 100644
--- a/glom/libglom/python_embed/py_glom_record.cc
+++ b/glom/libglom/python_embed/py_glom_record.cc
@@ -167,41 +167,27 @@ void PyGlomRecord::setitem(const boost::python::object& key, const boost::python
params->add_holder(field->get_holder(field_value));
params->add_holder(m_key_field->get_holder(m_key_field_value));
- Glib::ustring strQuery = "UPDATE \"" + m_table_name + "\"";
- strQuery += " SET \"" + field->get_name() + "\" = " + field->get_gda_holder_string();
- strQuery += " WHERE \"" + m_key_field->get_name() + "\" = " + m_key_field->get_gda_holder_string();
-
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(m_table_name);
+ builder->add_field_value_as_value(field->get_name(), field_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(m_key_field->get_name()),
+ builder->add_expr(m_key_field_value)));
+
bool updated = false;
- Glib::RefPtr<Gnome::Gda::Statement> stmt;
try
{
- Glib::RefPtr<Gnome::Gda::SqlParser> parser = m_connection->create_parser();
- stmt = parser->parse_string(strQuery);
-
+ updated = m_connection->statement_execute_non_select_builder(builder);
}
catch(const Glib::Exception& ex)
{
- std::cerr << "PyGlomRecord::setitem(): exception while parsing query: " << ex.what() << std::endl;
+ std::cerr << "PyGlomRecord::setitem(): exception while executing query: " << ex.what() << std::endl;
}
catch(const std::exception& ex)
{
- std::cerr << "PyGlomRecord::setitem(): exception while parsing query: " << ex.what() << std::endl;
- }
-
- if(stmt)
- {
- try
- {
- updated = m_connection->statement_execute_non_select(stmt, params);
- }
- catch(const Glib::Exception& ex)
- {
- std::cerr << "PyGlomRecord::setitem(): exception while executing query: " << ex.what() << std::endl;
- }
- catch(const std::exception& ex)
- {
- std::cerr << "PyGlomRecord::setitem(): exception while executing query: " << ex.what() << std::endl;
- }
+ std::cerr << "PyGlomRecord::setitem(): exception while executing query: " << ex.what() << std::endl;
}
if(!updated)
diff --git a/glom/libglom/python_embed/py_glom_related.cc b/glom/libglom/python_embed/py_glom_related.cc
index 1676d38..2f49217 100644
--- a/glom/libglom/python_embed/py_glom_related.cc
+++ b/glom/libglom/python_embed/py_glom_related.cc
@@ -86,17 +86,10 @@ boost::python::object PyGlomRelated::getitem(const boost::python::object& cppite
//TODO_Performance:
//Get the full field details so we can sqlize its value:
- sharedptr<Field> from_key_field;
- from_key_field = record->m_document->get_field(record->m_table_name, from_key);
+ sharedptr<const Field> from_key_field = record->m_document->get_field(record->m_table_name, from_key);
if(from_key_field)
- {
- Glib::ustring key_value_sqlized;
- //std::cout << "from_key_field=" << from_key_field->get_name() << ", from_key_value=" << from_key_value.to_string() << std::endl;
-
- if(!Conversions::value_is_empty(from_key_value)) //Do not link on null-values. That would cause us to link on 0, or "0".
- key_value_sqlized = from_key_field->sql(from_key_value);
-
- PyGlomRelatedRecord_SetRelationship(pyRelatedRecord, iterFind->second, key_value_sqlized, record->m_document);
+ {
+ PyGlomRelatedRecord_SetRelationship(pyRelatedRecord, iterFind->second, from_key_value, record->m_document);
//Store it in the cache:
boost::python::object objectRelatedRecord(pyRelatedRecord);
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.cc b/glom/libglom/python_embed/py_glom_relatedrecord.cc
index 59c5949..396a6d9 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.cc
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.cc
@@ -22,6 +22,7 @@
#include <libglom/python_embed/py_glom_record.h>
#include <libglom/python_embed/pygdavalue_conversions.h> //For pygda_value_as_pyobject().
#include <libglom/connectionpool.h>
+#include <libglom/data_structure/glomconversions.h>
#include <libglom/data_structure/field.h>
#include <glibmm/ustring.h>
@@ -61,91 +62,94 @@ boost::python::object PyGlomRelatedRecord::getitem(const boost::python::object&
//If the value has already been stored, then just return it again:
return glom_pygda_value_as_boost_pyobject(iterFind->second);
}
+
+ const Glib::ustring related_table = m_relationship->get_to_table();
+
+ //Check whether the field exists in the table.
+ //TODO_Performance: Do this without the useless Field information?
+ sharedptr<const Field> field = m_document->get_field(m_relationship->get_to_table(), field_name);
+ if(!field)
+ {
+ g_warning("PyGlomRelatedRecord::setitem(): field %s not found in table %s", field_name.c_str(), m_relationship->get_to_table().c_str());
+ PyErr_SetString(PyExc_IndexError, "field not found");
+ return boost::python::object();
+ }
else
{
- const Glib::ustring related_table = m_relationship->get_to_table();
-
- //Check whether the field exists in the table.
- //TODO_Performance: Do this without the useless Field information?
- sharedptr<const Field> field = m_document->get_field(m_relationship->get_to_table(), field_name);
- if(!field)
- g_warning("RelatedRecord_tp_as_mapping_getitem: field %s not found in table %s", field_name.c_str(), m_relationship->get_to_table().c_str());
- else
- {
- //Try to get the value from the database:
- //const Glib::ustring parent_key_name;
+ //Try to get the value from the database:
+ //const Glib::ustring parent_key_name;
#ifdef GLIBMM_EXCEPTIONS_ENABLED
- sharedptr<SharedConnection> sharedconnection = ConnectionPool::get_instance()->connect();
+ sharedptr<SharedConnection> sharedconnection = ConnectionPool::get_instance()->connect();
#else
- std::auto_ptr<ExceptionConnection> conn_error;
- sharedptr<SharedConnection> sharedconnection = ConnectionPool::get_instance()->connect(conn_error);
- // Ignore error, sharedconnection presence is checked below
+ std::auto_ptr<ExceptionConnection> conn_error;
+ sharedptr<SharedConnection> sharedconnection = ConnectionPool::get_instance()->connect(conn_error);
+ // Ignore error, sharedconnection presence is checked below
#endif
- if(sharedconnection)
- {
- Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
-
- const Glib::ustring related_key_name = m_relationship->get_to_field();
-
- //Do not try to get a value based on a null key value:
- if(m_from_key_value_sqlized.empty())
- return boost::python::object();
-
- //Get the single value from the related records:
- const Glib::ustring sql_query = "SELECT \"" + related_table + "\".\"" + field_name + "\" FROM \"" + related_table + "\""
- + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + m_from_key_value_sqlized;
-
- /* TODO: Fix linking problems
- const App_Glom* app = App_Glom::get_application();
- if(app && app->get_show_sql_debug())
- {
- try
- {
- std::cout << "Debug: RelatedRecord_tp_as_mapping_getitem(): " << sql_query << std::endl;
- }
- catch(const Glib::Exception& ex)
- {
- std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
- }
- }*/
+ if(!sharedconnection)
+ {
+ PyErr_SetString(PyExc_IndexError, "connection not found");
+ return boost::python::object();
+ }
+
+ Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- // TODO: Does this behave well if this throws an exception?
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select(sql_query);
-#else
- std::auto_ptr<Glib::Error> error;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select(sql_query, Gnome::Gda::STATEMENT_MODEL_RANDOM_ACCESS, error);
- // Ignore error, datamodel return value is checked below
-#endif
- if(datamodel && datamodel->get_n_rows())
- {
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
-#else
- Gnome::Gda::Value value = datamodel->get_value_at(0, 0, error);
-#endif
- //g_warning("RelatedRecord_tp_as_mapping_getitem(): value from datamodel = %s", value.to_string().c_str());
-
- //Cache it, in case it's asked-for again.
- m_map_field_values[field_name] = value;
- return glom_pygda_value_as_boost_pyobject(value);
- }
- else if(!datamodel)
- {
- g_warning("RelatedRecord_tp_as_mapping_getitem(): The datamodel was null.");
- ConnectionPool::handle_error_cerr_only();
- RelatedRecord_HandlePythonError();
- }
- else
- {
- g_warning("RelatedRecord_tp_as_mapping_getitem(): No related records exist yet for relationship %s.", m_relationship->get_name().c_str());
- }
+ const Glib::ustring related_key_name = m_relationship->get_to_field();
+
+ //Do not try to get a value based on a null key value:
+ if(Conversions::value_is_empty(m_from_key_value))
+ {
+ PyErr_SetString(PyExc_IndexError, "connection not found");
+ return boost::python::object();
+ }
+
+ //Get the single value from the related records:
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(field_name, related_table);
+ builder->select_add_target(related_table);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(related_key_name), //TODO: It would nice to specify the table name here too.
+ builder->add_expr(m_from_key_value)));
+
+ /* TODO: Fix linking problems
+ const App_Glom* app = App_Glom::get_application();
+ if(app && app->get_show_sql_debug())
+ {
+ try
+ {
+ std::cout << "Debug: PyGlomRelatedRecord::setitem()(): " << sql_query << std::endl;
}
+ catch(const Glib::Exception& ex)
+ {
+ std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
+ }
+ }*/
+
+ // TODO: Does this behave well if this throws an exception?
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select_builder(builder);
+ if(datamodel && datamodel->get_n_rows())
+ {
+ const Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
+ //g_warning("PyGlomRelatedRecord::setitem()(): value from datamodel = %s", value.to_string().c_str());
+
+ //Cache it, in case it's asked-for again.
+ m_map_field_values[field_name] = value;
+ return glom_pygda_value_as_boost_pyobject(value);
+ }
+ else if(!datamodel)
+ {
+ g_warning("PyGlomRelatedRecord::setitem()(): The datamodel was null.");
+ ConnectionPool::handle_error_cerr_only();
+ RelatedRecord_HandlePythonError();
+ }
+ else
+ {
+ g_warning("PyGlomRelatedRecord::setitem()(): No related records exist yet for relationship %s.", m_relationship->get_name().c_str());
}
}
- g_warning("RelatedRecord_tp_as_mapping_getitem(): return null.");
- PyErr_SetString(PyExc_IndexError, "field not found");
+ g_warning("PyGlomRelatedRecord::setitem()(): return null.");
return boost::python::object();
}
@@ -182,32 +186,30 @@ boost::python::object PyGlomRelatedRecord::generic_aggregate(const std::string&
const Glib::ustring related_key_name = m_relationship->get_to_field();
//Do not try to get a value based on a null key value:
- if(m_from_key_value_sqlized.empty())
+ if(Conversions::value_is_empty(m_from_key_value))
{
return boost::python::object();
}
//Get the aggregate value from the related records:
- const Glib::ustring sql_query = "SELECT " + aggregate + "(\"" + related_table + "\".\"" + field_name + "\") FROM \"" + related_table + "\""
- + " WHERE \"" + related_table + "\".\"" + related_key_name + "\" = " + m_from_key_value_sqlized;
-
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->add_function(aggregate, builder->add_id(field_name)); //TODO: It would be nice to specify the table here too.
+ builder->select_add_target(related_table);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(related_key_name), //TODO: It would nice to specify the table name here too.
+ builder->add_expr(m_from_key_value)));
+
+
//std::cout << "PyGlomRelatedRecord: Executing: " << sql_query << std::endl;
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select(sql_query);
-#else
- std::auto_ptr<Glib::Error> error;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select(sql_query, Gnome::Gda::STATEMENT_MODEL_RANDOM_ACCESS, error);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = gda_connection->statement_execute_select_builder(builder);
// Ignore the error: The case that the command execution didn't return
// a datamodel is handled below.
-#endif
if(datamodel && datamodel->get_n_rows())
{
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
-#else
- Gnome::Gda::Value value = datamodel->get_value_at(0, 0, error);
-#endif
//g_warning("RelatedRecord_generic_aggregate(): value from datamodel = %s", value.to_string().c_str());
//Cache it, in case it's asked-for again.
@@ -248,11 +250,11 @@ boost::python::object PyGlomRelatedRecord::max(const std::string& field_name) co
return generic_aggregate(field_name, "max");
}
-void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Glib::ustring& from_key_value_sqlized, Document* document)
+void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Gnome::Gda::Value& from_key_value, Document* document)
{
self->m_relationship = relationship;
- self->m_from_key_value_sqlized = from_key_value_sqlized;
+ self->m_from_key_value = from_key_value;
self->m_document = document;
}
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.h b/glom/libglom/python_embed/py_glom_relatedrecord.h
index c4dad58..7c92734 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.h
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.h
@@ -56,14 +56,14 @@ public:
Document* m_document;
sharedptr<const Relationship> m_relationship;
- Glib::ustring m_from_key_value_sqlized;
+ Gnome::Gda::Value m_from_key_value;
//Available, for instance, in python via record["name_first"]
typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_field_values;
mutable type_map_field_values m_map_field_values; //A cache.
};
-void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Glib::ustring& from_key_value_sqlized, Document* document);
+void PyGlomRelatedRecord_SetRelationship(PyGlomRelatedRecord* self, const sharedptr<const Relationship>& relationship, const Gnome::Gda::Value& from_key_value, Document* document);
/*
void PyGlomRelatedRecord_SetConnection(PyGlomRelatedRecord* self, const Glib::RefPtr<Gnome::Gda::Connection>& connection);
diff --git a/glom/mode_data/box_data_calendar_related.cc b/glom/mode_data/box_data_calendar_related.cc
index bf919c8..327e93f 100644
--- a/glom/mode_data/box_data_calendar_related.cc
+++ b/glom/mode_data/box_data_calendar_related.cc
@@ -285,14 +285,16 @@ void Box_Data_Calendar_Related::on_record_added(const Gnome::Gda::Value& primary
//Create the link by setting the foreign key
if(m_key_field && m_portal)
- {
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder(m_key_field->get_holder(m_key_value));
- params->add_holder(field_primary_key->get_holder(primary_key_value));
- Glib::ustring strQuery = "UPDATE \"" + m_portal->get_table_used(Glib::ustring() /* not relevant */) + "\"";
- strQuery += " SET \"" + /* get_table_name() + "." +*/ m_key_field->get_name() + "\" = " + m_key_field->get_gda_holder_string();
- strQuery += " WHERE \"" + get_table_name() + "\".\"" + field_primary_key->get_name() + "\" = " + field_primary_key->get_gda_holder_string();
- const bool test = query_execute(strQuery, params);
+ {
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(m_portal->get_table_used(Glib::ustring() /* not relevant */));
+ builder->add_field_value_as_value(m_key_field->get_name(), m_key_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(field_primary_key->get_name()),
+ builder->add_expr_as_value(primary_key_value)));
+
+ const bool test = query_execute(builder);
if(test)
{
//Show it on the view, if it's visible:
diff --git a/glom/mode_data/box_data_portal.cc b/glom/mode_data/box_data_portal.cc
index feef1a2..7d653c9 100644
--- a/glom/mode_data/box_data_portal.cc
+++ b/glom/mode_data/box_data_portal.cc
@@ -108,17 +108,19 @@ void Box_Data_Portal::make_record_related(const Gnome::Gda::Value& related_recor
std::cerr << "Box_Data_Portal::make_record_related(): m_portal was null." << std::endl;
}
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder(m_key_field->get_holder(m_key_value));
- params->add_holder(field_primary_key->get_holder(related_record_primary_key_value));
- Glib::ustring strQuery = "UPDATE \"" + m_portal->get_table_used(Glib::ustring() /* not relevant */) + "\"";
- strQuery += " SET \"" + /* get_table_name() + "." +*/ m_key_field->get_name() + "\" = " + m_key_field->get_gda_holder_string();
- strQuery += " WHERE \"" + get_table_name() + "\".\"" + field_primary_key->get_name() + "\" = " + field_primary_key->get_gda_holder_string();
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(m_portal->get_table_used(Glib::ustring() /* not relevant */));
+ builder->add_field_value_as_value(m_key_field->get_name(), m_key_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(field_primary_key->get_name()),
+ builder->add_expr_as_value(related_record_primary_key_value)));
+
//std::cout << "Box_Data_Portal::make_record_related(): setting value in db=" << primary_key_value.to_string() << std::endl;
- const bool test = query_execute(strQuery, params);
+ const bool test = query_execute(builder);
if(!test)
{
- std::cerr << "Box_Data_Portal::make_record_related(): SQL query failed: " << strQuery << std::endl;
+ std::cerr << "Box_Data_Portal::make_record_related(): SQL query failed." << std::endl;
}
}
diff --git a/glom/mode_design/dialog_database_preferences.cc b/glom/mode_design/dialog_database_preferences.cc
index b515147..0867aa4 100644
--- a/glom/mode_design/dialog_database_preferences.cc
+++ b/glom/mode_design/dialog_database_preferences.cc
@@ -94,13 +94,20 @@ void Dialog_Database_Preferences::on_treeview_cell_edited_next_value(const Glib:
const Glib::ustring field_name = row[m_columns.m_col_field];
const Gnome::Gda::Value next_value = Conversions::parse_value(new_value);
-
- const Glib::ustring sql_query = "UPDATE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\" SET "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE "\" = " + next_value.to_string() +
- " WHERE \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME "\" = '" + table_name + "' AND "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME "\" = '" + field_name +"'";
-
- const bool test = query_execute(sql_query);
+
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_UPDATE);
+ builder->set_table(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->add_field_value_as_value(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE, next_value);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_AND,
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME),
+ builder->add_expr(table_name)),
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+ builder->add_id(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME),
+ builder->add_expr(field_name))));
+
+ const bool test = query_execute(builder);
if(!test)
std::cerr << "Dialog_Database_Preferences::on_treeview_cell_edited_next_value(): UPDATE failed." << std::endl;
}
@@ -132,15 +139,19 @@ void Dialog_Database_Preferences::load_from_document()
//Show the auto-increment values:
m_model_autoincrements->clear();
- const Glib::ustring sql_query = "SELECT "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME "\", "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME "\", "
- "\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE "\""
- " FROM \"" GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME "\"";
-
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME,
+ GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME,
+ GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->select_add_field(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE,
+ GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+ builder->select_add_target(GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME);
+
NumericFormat numeric_format; //ignored
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(builder);
if(!datamodel)
{
std::cerr << "Dialog_Database_Preferences::load_from_document(): Gda::DataModel is NULL." << std::endl;
diff --git a/glom/mode_design/fields/box_db_table_definition.cc b/glom/mode_design/fields/box_db_table_definition.cc
index 3dd85c7..df7cc93 100644
--- a/glom/mode_design/fields/box_db_table_definition.cc
+++ b/glom/mode_design/fields/box_db_table_definition.cc
@@ -623,14 +623,18 @@ void Box_DB_Table_Definition::fill_fields()
bool Box_DB_Table_Definition::field_has_null_values(const sharedptr<const Field>& field)
{
- //TODO: Use SQL paramters?
//Note that "= Null" doesn't work, though it doesn't error either.
//Note also that SELECT COUNT always returns 0 if all the values are NULL, so we can't use that to be more efficient.
- const Glib::ustring sql_query = "SELECT \"" + field->get_name() + "\" FROM \"" + m_table_name + "\" WHERE \"" + m_table_name + "\".\"" + field->get_name() + "\" IS NULL LIMIT 1";
- //std::cout << "sql_query: " << sql_query << std::endl;
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->select_add_field(field->get_name(), m_table_name);
+ builder->select_add_target(m_table_name);
+ builder->set_where(
+ builder->add_cond(Gnome::Gda::SQL_OPERATOR_TYPE_ISNULL,
+ builder->add_id(field->get_name()))); //TODO: It would nice to specify the table name here too.
long null_count = 0;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(builder);
if(datamodel)
{
if(datamodel->get_n_rows() && datamodel->get_n_columns())
@@ -641,7 +645,7 @@ bool Box_DB_Table_Definition::field_has_null_values(const sharedptr<const Field>
}
else
{
- std::cerr << "Box_DB_Table_Definition::field_has_null_values(): query failed: " << sql_query << std::endl;
+ std::cerr << "Box_DB_Table_Definition::field_has_null_values(): query failed." << std::endl;
}
return null_count > 0;
@@ -652,7 +656,8 @@ bool Box_DB_Table_Definition::field_has_non_unique_values(const sharedptr<const
long count_distinct = 0;
long count_all = 0;
- //Count the distint rows:
+ //TODO: Use SqlBuilder. I asked on the mailing list about how to use DISTINCT with it. murrayc.
+ //Count the distinct rows:
const Glib::ustring sql_query_distinct = "SELECT DISTINCT \"" + field->get_name() + "\" FROM \"" + m_table_name + "\"";
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query_distinct);
@@ -667,9 +672,12 @@ bool Box_DB_Table_Definition::field_has_non_unique_values(const sharedptr<const
}
//Count all rows, to compare. TODO_performance: Is there a more efficient way to do this? Maybe count(*), which apparently doesn't ignore NULL rows like count(somefield) would.
- const Glib::ustring sql_query_all = "SELECT \"" + field->get_name() + "\" FROM \"" + m_table_name + "\"";
-
- datamodel = query_execute_select(sql_query_all);
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder_query_all =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder_query_all->select_add_field(field->get_name(), m_table_name);
+ builder_query_all->select_add_target(m_table_name);
+
+ datamodel = query_execute_select(builder_query_all);
if(datamodel)
{
count_all = datamodel->get_n_rows();
diff --git a/glom/report_builder.cc b/glom/report_builder.cc
index d1257fb..0052d98 100644
--- a/glom/report_builder.cc
+++ b/glom/report_builder.cc
@@ -175,6 +175,7 @@ void ReportBuilder::report_build_groupby(const FoundSet& found_set_parent, xmlpp
fill_full_field_details(found_set_parent.m_table_name, field_group_by);
//Get the possible group values, ignoring repeats by using GROUP BY.
+ //TODO: Use SqlBuilder:
const Glib::ustring group_field_table_name = field_group_by->get_table_used(found_set_parent.m_table_name);
Glib::ustring sql_query = "SELECT \"" + group_field_table_name + "\".\"" + field_group_by->get_name() + "\""
" FROM \"" + group_field_table_name + "\"";
@@ -182,7 +183,7 @@ void ReportBuilder::report_build_groupby(const FoundSet& found_set_parent, xmlpp
if(!found_set_parent.m_where_clause.empty())
sql_query += " WHERE " + found_set_parent.m_where_clause;
- sql_query += " GROUP BY " + field_group_by->get_name(); //rTODO: And restrict to the current found set.
+ sql_query += " GROUP BY " + field_group_by->get_name(); //TODO: And restrict to the current found set.
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(sql_query);
if(datamodel)
@@ -384,6 +385,7 @@ void ReportBuilder::report_build_records_field(const FoundSet& found_set, xmlpp:
{
//In this case it can only be a system preferences field.
//So let's get that data here:
+ //TODO: Use SqlBuilder when we know how to use LIMIT with it. I asked on the libgda mailing list. murrayc.
const Glib::ustring table_used = field->get_table_used(found_set.m_table_name);
const Glib::ustring query = "SELECT \"" + table_used + "\".\"" + field->get_name() + "\" FROM \""+ table_used + "\" LIMIT 1";
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute_select(query);
diff --git a/glom/utility_widgets/db_adddel/db_adddel.cc b/glom/utility_widgets/db_adddel/db_adddel.cc
index 279b729..9ffce98 100644
--- a/glom/utility_widgets/db_adddel/db_adddel.cc
+++ b/glom/utility_widgets/db_adddel/db_adddel.cc
@@ -2551,11 +2551,6 @@ void DbAddDel::user_changed(const Gtk::TreeModel::iterator& row, guint col)
const bool bTest = set_field_value_in_database(field_in_record, row, field_value, false /* don't use current calculations */, window);
-
- //Glib::ustring strQuery = "UPDATE \"" + table_name + "\"";
- //strQuery += " SET " + /* table_name + "." + postgres does not seem to like the table name here */ strFieldName + " = " + field.sql(field_value, connection);
- //strQuery += " WHERE " + table_name + "." + primary_key_field.get_name() + " = " + primary_key_field.sql(primary_key_value, connection);
- //bool bTest = query_execute(strQuery);
if(!bTest)
{
//Update failed.
diff --git a/glom/utility_widgets/db_adddel/glom_db_treemodel.cc b/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
index a83dc17..8fa203a 100644
--- a/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
+++ b/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
@@ -958,15 +958,17 @@ void DbTreeModel::get_record_counts(gulong& total, gulong& found) const
{
//Ask the database how many records there are in the whole table:
//TODO: Apparently, this is very slow:
- const Glib::ustring sql_query = "SELECT count(*) FROM \"" + m_found_set.m_table_name + "\"";
- Glib::RefPtr<Gnome::Gda::SqlParser> parser = m_connection->get_gda_connection()->create_parser();
+
+ Glib::RefPtr<Gnome::Gda::SqlBuilder> builder =
+ Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
+ builder->add_function("count", builder->add_id("*")); //TODO: Is * allowed here?
+ builder->select_add_target(m_found_set.m_table_name);
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
- Glib::RefPtr<Gnome::Gda::Statement> stmt = parser->parse_string(sql_query);
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = m_connection->get_gda_connection()->statement_execute_select(stmt);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = m_connection->get_gda_connection()->statement_execute_select_builder(builder);
#else
std::auto_ptr<Glib::Error> error;
- Glib::RefPtr<Gnome::Gda::Statement> stmt = parser->parse_string(sql_query, error);
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = m_connection->get_gda_connection()->statement_execute_select(stmt, Gnome::Gda::STATEMENT_MODEL_RANDOM_ACCESS, error);
+ Glib::RefPtr<Gnome::Gda::DataModel> datamodel = m_connection->get_gda_connection()->statement_execute_select_builder(builder, Gnome::Gda::STATEMENT_MODEL_RANDOM_ACCESS, error);
// Ignore error, datamodel presence is checked below
#endif //GLIBMM_EXCEPTIONS_ENABLED
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]