[glom/sqlbuilder2] More use of SqlBuilder. Almost finished.



commit aaebaf7e8a62b57e97453a2fd6719d42952a1b3a
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu May 20 09:02:10 2010 +0200

    More use of SqlBuilder. Almost finished.
    
    * glom/base_db.cc:
    * glom/libglom/data_structure/layout/usesrelationship.[h|cc]:
        Change get_sql_join_alias_definition() to get_sql_join_alias_definition().
    * glom/libglom/db_utils.[h|cc]: query_execute_select(): Add an optional
        use_cursor bool to use the non-random database access.
    * glom/libglom/utils.[h|cc]: Change build_sql_select_fields_to_get() to
        build_sql_select_add_fields_to_get().
        build_sql_select_with_where_clause(): Use SqlBuilder.
    * glom/utility_widgets/db_adddel/glom_db_treemodel.cc:
        refresh_from_database(): Use DbUtils::query_execute_select(), to simplify
        the code. This is possible now that the function is not in BaseDB.

 ChangeLog                                          |   28 +++-
 glom/base_db.cc                                    |   11 +-
 .../data_structure/layout/usesrelationship.cc      |   41 ++++--
 .../data_structure/layout/usesrelationship.h       |    4 +-
 glom/libglom/db_utils.cc                           |   21 +++-
 glom/libglom/db_utils.h                            |    7 +-
 glom/libglom/utils.cc                              |  145 ++++++++------------
 glom/libglom/utils.h                               |    7 +-
 .../utility_widgets/db_adddel/glom_db_treemodel.cc |   67 +---------
 9 files changed, 138 insertions(+), 193 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d048fbb..1d46a1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,23 @@
+2010-05-19  Murray Cumming  <murrayc murrayc com>
+
+	More use of SqlBuilder. Almost finished.
+
+	* glom/base_db.cc:
+	* glom/libglom/data_structure/layout/usesrelationship.[h|cc]:
+    Change get_sql_join_alias_definition() to get_sql_join_alias_definition().
+	* glom/libglom/db_utils.[h|cc]: query_execute_select(): Add an optional
+    use_cursor bool to use the non-random database access.
+	* glom/libglom/utils.[h|cc]: Change build_sql_select_fields_to_get() to
+    build_sql_select_add_fields_to_get().
+    build_sql_select_with_where_clause(): Use SqlBuilder.
+	* glom/utility_widgets/db_adddel/glom_db_treemodel.cc:
+    refresh_from_database(): Use DbUtils::query_execute_select(), to simplify
+    the code. This is possible now that the function is not in BaseDB.
+
 2010-05-13  Murray Cumming  <murrayc murrayc com>
 
 	DbUtils: Catch SqlError exception.
-	
+
 	* glom/libglom/db_utils.cc: query_execute_select(), query_execute_select():
 	Catch SqlError too, as this seems to be thrown too.
 
@@ -9,17 +25,17 @@
 
 	DbUtils::query_execute(): Remove params parameter.
 
-	* glom/libglom/db_utils.[h|cc]: query_execute(): Remove the unused params 
+	* glom/libglom/db_utils.[h|cc]: query_execute(): Remove the unused params
 	parameter.
 
 2010-05-13  Murray Cumming  <murrayc murrayc com>
 
 	Use SqlBuilder in all possible remaining places.
-	
-	* glom/libglom/db_utils.[h|cc]: Renamed query_execute(string) to 
+
+	* glom/libglom/db_utils.[h|cc]: Renamed query_execute(string) to
 	query_execute_string() so we catch uses of it that could use SqlBuilder.
 
-	* glom/base_db.cc: Replaced some INSERT and DELETE string sql queries 
+	* glom/base_db.cc: Replaced some INSERT and DELETE string sql queries
 	with SqlBuilder.
 	* glom/base_db_table_data.cc:
 	* glom/libglom/db_utils.cc:
@@ -33,7 +49,7 @@
 
 	Remove redundant BaseDb::query_execute*() methods.
 
-	* glom/base_db.[h|cc]: Removed query_execute_select() and query_execute(). 
+	* glom/base_db.[h|cc]: Removed query_execute_select() and query_execute().
 	The same methods in DbUtils replace them.
 	* glom/libglom/db_utils.[h|cc]: Removed the query_execute_select(string) override.
 	* glom/mode_data/box_data_calendar_related.cc:
diff --git a/glom/base_db.cc b/glom/base_db.cc
index 1c5ac2e..79c2535 100644
--- a/glom/base_db.cc
+++ b/glom/base_db.cc
@@ -1887,6 +1887,7 @@ bool Base_DB::get_primary_key_is_in_foundset(const FoundSet& found_set, const Gn
 
 int Base_DB::count_rows_returned_by(const Glib::RefPtr<Gnome::Gda::SqlBuilder>& sql_query)
 {
+  std::cout << "Base_DB::count_rows_returned_by(): debug: input sql_query=" << Utils::sqlbuilder_get_full_query(sql_query) << std::endl;
   if(!sql_query)
   {
     std::cerr << "Base_DB::count_rows_returned_by(): sql_query was null." << std::endl;
@@ -1976,12 +1977,10 @@ void Base_DB::set_found_set_where_clause_for_portal(FoundSet& found_set, const s
         fields.push_back(item_field);
     }
 
-    Glib::ustring sql_part_from;
-    Glib::ustring sql_part_leftouterjoin;
-    const Glib::ustring sql_part_fields = Utils::build_sql_select_fields_to_get(
-      found_set.m_table_name, fields, found_set.m_sort_clause,
-      sql_part_from, sql_part_leftouterjoin);
-    found_set.m_extra_group_by = "GROUP BY " + sql_part_fields;
+    //TODO:?
+    //const Glib::ustring sql_part_fields = Utils::build_sql_select_fields_to_get(
+    //  found_set.m_table_name, fields, found_set.m_sort_clause);
+    //found_set.m_extra_group_by = "GROUP BY " + sql_part_fields;
 
 
     //Adjust the WHERE clause appropriately for the extra JOIN:
diff --git a/glom/libglom/data_structure/layout/usesrelationship.cc b/glom/libglom/data_structure/layout/usesrelationship.cc
index bff8037..36e8aed 100644
--- a/glom/libglom/data_structure/layout/usesrelationship.cc
+++ b/glom/libglom/data_structure/layout/usesrelationship.cc
@@ -40,7 +40,7 @@ UsesRelationship::~UsesRelationship()
 
 bool UsesRelationship::operator==(const UsesRelationship& src) const
 {
-  return (m_relationship == src.m_relationship) 
+  return (m_relationship == src.m_relationship)
          && (m_related_relationship == src.m_related_relationship);
 }
 
@@ -150,10 +150,10 @@ Glib::ustring UsesRelationship::get_title_singular_used(const Glib::ustring& par
   sharedptr<Relationship> used = m_related_relationship;
   if(!used)
     used = m_relationship;
-    
+
   if(!used)
     return Glib::ustring();
-    
+
   const Glib::ustring result = used->get_title_singular();
   if(!result.empty())
     return result;
@@ -218,29 +218,38 @@ Glib::ustring UsesRelationship::get_sql_join_alias_name() const
   return result;
 }
 
-Glib::ustring UsesRelationship::get_sql_join_alias_definition() const
+void UsesRelationship::add_sql_join_alias_definition(const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder) const
 {
-  Glib::ustring result;
+  // Specify an alias, to avoid ambiguity when using 2 relationships to the same table.
+  const Glib::ustring alias_name = get_sql_join_alias_name();
+  const guint to_target_id = builder->select_add_target(m_relationship->get_to_table(), alias_name);
 
+  // Add the JOIN:
   if(!get_has_related_relationship_name())
   {
-    result = " LEFT OUTER JOIN \"" + m_relationship->get_to_table() + "\""
-             + " AS \"" + get_sql_join_alias_name() + "\"" //Specify an alias, to avoid ambiguity when using 2 relationships to the same table.
-             + " ON (\"" + m_relationship->get_from_table() + "\".\"" + m_relationship->get_from_field() + "\" = \""
-             + get_sql_join_alias_name() + "\".\"" + m_relationship->get_to_field() + "\")";
+    builder->select_join_targets(
+      builder->add_id(m_relationship->get_from_table()), //TODO: Must we use the ID from select_add_target_id()?
+      to_target_id,
+      Gnome::Gda::SQL_SELECT_JOIN_LEFT,
+      builder->add_cond(
+        Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+        builder->add_id("\"" + m_relationship->get_from_table() + "\".\"" + m_relationship->get_from_field() + "\""),
+        builder->add_id("\"" + alias_name + "\".\"" + m_relationship->get_to_field() + "\"") ) );
   }
   else
   {
      UsesRelationship parent_relationship;
      parent_relationship.set_relationship(m_relationship);
-     result = " LEFT OUTER JOIN \"" + m_related_relationship->get_to_table() + "\""
-             + " AS \"" + get_sql_join_alias_name() + "\"" //Specify an alias, to avoid ambiguity when using 2 relationships to the same table.
-             + " ON (\"" + parent_relationship.get_sql_join_alias_name() + "\".\"" + m_related_relationship->get_from_field() + "\" = \""
-             + get_sql_join_alias_name() + "\".\"" + m_related_relationship->get_to_field() + "\")";
+
+     builder->select_join_targets(
+      builder->add_id(m_relationship->get_from_table()), //TODO: Must we use the ID from select_add_target_id()?
+      to_target_id,
+      Gnome::Gda::SQL_SELECT_JOIN_LEFT,
+      builder->add_cond(
+        Gnome::Gda::SQL_OPERATOR_TYPE_EQ,
+        builder->add_id("\"" + parent_relationship.get_sql_join_alias_name() + "\".\"" + m_related_relationship->get_from_field() + "\""),
+        builder->add_id("\"" + alias_name + "\".\"" + m_relationship->get_to_field() + "\"") ) );
   }
-  return result;
 }
 
 } //namespace Glom
-
-
diff --git a/glom/libglom/data_structure/layout/usesrelationship.h b/glom/libglom/data_structure/layout/usesrelationship.h
index c2c236a..77a6193 100644
--- a/glom/libglom/data_structure/layout/usesrelationship.h
+++ b/glom/libglom/data_structure/layout/usesrelationship.h
@@ -106,10 +106,10 @@ public:
    */ 
   Glib::ustring get_sql_join_alias_name() const;
 
-  /** Get a SQL fragment that defines the alias name as returned by 
+  /** Define the alias name as returned by 
    * get_sql_join_alias_name().
    */ 
-  Glib::ustring get_sql_join_alias_definition() const;
+  void add_sql_join_alias_definition(const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder) const;
 
   /** Get the item's alias name, if it uses a relationship, or just get its table name.
    * @param parent_table The table to which the item (or its relatinoships) belong.
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 76309d0..9b5bfa5 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -1526,7 +1526,7 @@ bool insert_example_data(Document* document, const Glib::ustring& table_name)
 }
 
 //static:
-Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder)
+Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder, bool use_cursor)
 {
   Glib::RefPtr<Gnome::Gda::DataModel> result;
 
@@ -1550,7 +1550,13 @@ Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(const Glib::RefPtr<cons
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
   try
   {
-    result = gda_connection->statement_execute_select_builder(builder);
+    if(use_cursor)
+    {
+      //Specify the STATEMENT_MODEL_CURSOR, so that libgda only gets the rows that we actually use.
+      result = gda_connection->statement_execute_select_builder(builder, Gnome::Gda::STATEMENT_MODEL_CURSOR_FORWARD);
+    }
+    else
+      result = gda_connection->statement_execute_select_builder(builder);
   }
   catch(const Gnome::Gda::ConnectionError& ex)
   {
@@ -1570,7 +1576,14 @@ Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(const Glib::RefPtr<cons
   }
 
 #else
-  result = gda_connection->statement_execute_select_builder(builder, ex);
+  if(use_cursor)
+  {
+    //Specify the STATEMENT_MODEL_CURSOR, so that libgda only gets the rows that we actually use.
+    result = gda_connection->statement_execute_select_builder(builder, Gnome::Gda::STATEMENT_MODEL_CURSOR_FORWARD, ex);
+  }
+  else
+    result = gda_connection->statement_execute_select_builder(builder, ex);
+
   if(ex.get())
     std::cerr << "debug: query_execute_select(): Glib::Error from statement_execute_select_builder(): " << ex->what() << std::endl;
 #endif //GLIBMM_EXCEPTIONS_ENABLED
@@ -1696,7 +1709,7 @@ bool query_execute(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder)
     std::cerr << "  full_query: " << full_query << std::endl;
     return false;
   }
-  catch(const Gnome::Gda::SqlError& ex) //TODO: Make sure that statement_execute_select_builder() is documented as throwing this.
+  catch(const Gnome::Gda::SqlError& ex) //TODO: Make sure that statement_execute_non_select_builder() is documented as throwing this.
   {
     std::cerr << "debug: query_execute_select(): SqlError: exception from statement_execute_non_select_builder(): " << ex.what() << std::endl;
     const std::string full_query = Utils::sqlbuilder_get_full_query(builder);
diff --git a/glom/libglom/db_utils.h b/glom/libglom/db_utils.h
index 9bcd475..2690289 100644
--- a/glom/libglom/db_utils.h
+++ b/glom/libglom/db_utils.h
@@ -73,9 +73,12 @@ bool drop_column(const Glib::ustring& table_name, const Glib::ustring& field_nam
 bool insert_example_data(Document* document, const Glib::ustring& table_name);
 
 /** Execute a SQL Select command, returning the result.
-  */
+ * @param builder The finished SqlBuilder object.
+ * @use_cursor Whether the data model should be cursor-based (not allowing random access).
+ */
 Glib::RefPtr<Gnome::Gda::DataModel> query_execute_select(
-  const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder);
+  const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder,
+  bool use_cursor = false);
 
 
 /** Execute a SQL non-select command, returning true if it succeeded.
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index ad7e81b..e62ec55 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -239,13 +239,8 @@ static void add_to_relationships_list(type_list_relationships& list_relationship
 
 }
 
-
-Glib::ustring Utils::build_sql_select_fields_to_get(const Glib::ustring& table_name, const type_vecConstLayoutFields& fieldsToGet, const type_sort_clause& sort_clause, Glib::ustring& sql_part_from, Glib::ustring& sql_part_leftouterjoin)
+void Utils::build_sql_select_add_fields_to_get(const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder, const Glib::ustring& table_name, const type_vecConstLayoutFields& fieldsToGet, const type_sort_clause& sort_clause)
 {
-  //Initialize output parameters:
-  sql_part_from = Glib::ustring();
-  sql_part_leftouterjoin = Glib::ustring();
-
   //Get all relationships used in the query:
   typedef std::list< sharedptr<const UsesRelationship> > type_list_relationships;
   type_list_relationships list_relationships;
@@ -261,10 +256,27 @@ Glib::ustring Utils::build_sql_select_fields_to_get(const Glib::ustring& table_n
     sharedptr<const LayoutItem_Field> layout_item = iter->first;
     add_to_relationships_list(list_relationships, layout_item);
   }
-
-
-  Glib::ustring sql_part_fields;
-
+  
+  
+  
+  //LEFT OUTER JOIN will get the field values from the other tables,
+  //and give us our fields for this table even if there is no corresponding value in the other table.
+  for(type_list_relationships::const_iterator iter = list_relationships.begin(); iter != list_relationships.end(); ++iter)
+  {
+    sharedptr<const UsesRelationship> uses_relationship = *iter;
+    sharedptr<const Relationship> relationship = uses_relationship->get_relationship();
+    if(relationship->get_has_fields()) //TODO: Handle related_record has_fields.
+    {
+      uses_relationship->add_sql_join_alias_definition(builder);
+    }
+    else if(relationship->get_has_to_table())
+    {
+      //It is a relationship that only specifies the table, without specifying linking fields:
+      builder->select_add_target(relationship->get_to_table());
+    }
+  }
+  
+  bool one_added = false;
   for(type_vecConstLayoutFields::const_iterator iter = fieldsToGet.begin(); iter != fieldsToGet.end(); ++iter)
   {
     Glib::ustring one_sql_part;
@@ -276,86 +288,44 @@ Glib::ustring Utils::build_sql_select_fields_to_get(const Glib::ustring& table_n
       continue;
     }
 
-    bool is_summary = false;
+    //Get the parent, such as the table name, or the alias name for the join:
+    const Glib::ustring parent = layout_item->get_sql_table_or_join_alias_name(table_name);
+      
     const LayoutItem_FieldSummary* fieldsummary = dynamic_cast<const LayoutItem_FieldSummary*>(layout_item.obj());
     if(fieldsummary)
-      is_summary = true;
-
-    //Add, for instance, "SUM(":
-    if(is_summary)
-      one_sql_part += fieldsummary->get_summary_type_sql() + '(';
-
-    one_sql_part += layout_item->get_sql_name(table_name);
-
-    //Close the summary bracket if necessary.
-    if(is_summary)
-      one_sql_part +=  ')';
-
-    //Append it to the big string of fields:
-    if(!one_sql_part.empty())
     {
-      if(!sql_part_fields.empty())
-        sql_part_fields += ", ";
-
-      sql_part_fields += one_sql_part;
+      builder->add_function(
+        fieldsummary->get_summary_type_sql(),
+        builder->add_id(layout_item->get_sql_name(table_name)) ); //TODO: It would be nice to specify the table here too.
     }
+    else
+      builder->select_add_field(layout_item->get_name(), parent);
+  
+    
+    one_added = true;
   }
 
-  if(sql_part_fields.empty())
+  if(!one_added)
   {
-    std::cerr << "Utils::build_sql_select_fields_to_get(): sql_part_fields.empty(): fieldsToGet.size()=" << fieldsToGet.size() << std::endl;
-    return sql_part_fields;
-  }
-
-  //LEFT OUTER JOIN will get the field values from the other tables,
-  //and give us our fields for this table even if there is no corresponding value in the other table.
-  for(type_list_relationships::const_iterator iter = list_relationships.begin(); iter != list_relationships.end(); ++iter)
-  {
-    sharedptr<const UsesRelationship> uses_relationship = *iter;
-    sharedptr<const Relationship> relationship = uses_relationship->get_relationship();
-    if(relationship->get_has_fields()) //TODO: Handle related_record has_fields.
-    {
-      sql_part_leftouterjoin += uses_relationship->get_sql_join_alias_definition();
-    }
-    else if(relationship->get_has_to_table())
-    {
-      //It is a relationship that only specifies the table, without specifying linking fields:
-      if(!(sql_part_from.empty()))
-        sql_part_from += ", ";
-
-      sql_part_from += relationship->get_to_table();
-    }
+    std::cerr << "Utils::build_sql_select_fields_to_get(): No fields added: fieldsToGet.size()=" << fieldsToGet.size() << std::endl;
+    return;
   }
-
-  return sql_part_fields;
 }
 
 
 Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_select_with_where_clause(const Glib::ustring& table_name, const type_vecConstLayoutFields& fieldsToGet, const Gnome::Gda::SqlExpr& where_clause, const Glib::ustring& extra_join, const type_sort_clause& sort_clause, const Glib::ustring& extra_group_by, guint limit)
 {
-
   //Build the whole SQL statement:
   Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Gnome::Gda::SqlBuilder::create(Gnome::Gda::SQL_STATEMENT_SELECT);
   builder->select_add_target(table_name);
 
-  //Get the fields to SELECT, plus the tables that they are selected FROM.
-  Glib::ustring sql_part_from;
-  Glib::ustring sql_part_leftouterjoin;
-  //TODO: sql_sort_clause_ids;
-
-/* TODO:
-  Utils::build_sql_select_add_fields_to_get(builder, table_name, fieldsToGet, sort_clause, sql_part_from, sql_part_leftouterjoin);
+  //Add the fields to SELECT, plus the tables that they are selected FROM.
+  Utils::build_sql_select_add_fields_to_get(builder, table_name, fieldsToGet, sort_clause);
   //builder->select_add_field(primary_key->get_name(), table_name);
-
-  if(!sql_part_from.empty())
-    result += (',' + sql_part_from);
-
-  if(!extra_join.empty())
-    sql_part_leftouterjoin += (' ' + extra_join + ' ');
-
-  if(!sql_part_leftouterjoin.empty())
-    result += (' ' + sql_part_leftouterjoin);
-
+  
+  //TODO:
+  //if(!extra_join.empty())
+ //   sql_part_leftouterjoin += (' ' + extra_join + ' ');
 
   //Add the WHERE clause:
   if(!where_clause.empty())
@@ -365,41 +335,36 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_select_with_where_clause(c
   }
 
   //Extra GROUP_BY clause for doubly-related records. This must be before the ORDER BY sort clause:
-  if(!extra_group_by.empty())
-  {
-    result += (' ' + extra_group_by + ' ');
-  }
+  //TODO:
+  //if(!extra_group_by.empty())
+  //{
+  //  result += (' ' + extra_group_by + ' ');
+  //}
 
   //Sort clause:
   if(!sort_clause.empty())
   {
-    Glib::ustring str_sort_clause;
-    for(type_sort_clause::const_iterator iter = sort_clause.begin(); iter != sort_clause.end(); ++iter)
+   for(type_sort_clause::const_iterator iter = sort_clause.begin(); iter != sort_clause.end(); ++iter)
     {
       sharedptr<const LayoutItem_Field> layout_item = iter->first;
       if(layout_item)
       {
         const bool ascending = iter->second;
 
-        if(!str_sort_clause.empty())
-          str_sort_clause += ", ";
-
-        str_sort_clause += "\"" + layout_item->get_sql_table_or_join_alias_name(table_name) + "\".\"" + layout_item->get_name() + "\" " + (ascending ? "ASC" : "DESC");
+        //TODO: Avoid the need for the "."
+        builder->select_order_by(
+          builder->add_id(layout_item->get_sql_table_or_join_alias_name("\"" + table_name) + "\".\"" + layout_item->get_name() + "\""),
+          ascending);
       }
     }
-
-    if(!str_sort_clause.empty())
-      result += " ORDER BY " + str_sort_clause;
   }
 
   //LIMIT clause:
-  if(!result.empty() && limit > 0)
+  if(limit > 0)
   {
-    char pchLimit[10];
-    sprintf(pchLimit, "%d", limit);
-    result += " LIMIT " + Glib::ustring(pchLimit);
+    builder->select_set_limit(limit);
   }
-*/
+
   return builder;
 }
 
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index 3ffd985..a69994f 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -57,12 +57,11 @@ Gnome::Gda::SqlExpr build_combined_where_expression(const Gnome::Gda::SqlExpr& a
 /** Generate a SQL statement to SELECT field values,
  * even if the fields are in related (or doubly related) records.
  */
-Glib::ustring build_sql_select_fields_to_get(
+void build_sql_select_add_fields_to_get(
+  const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder,
   const Glib::ustring& table_name,
   const type_vecConstLayoutFields& fieldsToGet,
-  const type_sort_clause& sort_clause,
-  Glib::ustring& sql_part_from,
-  Glib::ustring& sql_part_leftouterjoin);
+  const type_sort_clause& sort_clause);
 
 /** Generate a SQL statement to SELECT field values,
  * even if the fields are in related (or doubly related) records,
diff --git a/glom/utility_widgets/db_adddel/glom_db_treemodel.cc b/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
index e78e35a..b845ba5 100644
--- a/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
+++ b/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
@@ -24,6 +24,7 @@
 #include <libglom/connectionpool.h>
 #include <libglom/data_structure/glomconversions.h> //For util_build_sql
 #include <libglom/utils.h>
+#include <libglom/db_utils.h>
 
 #include "glom/application.h"
 
@@ -273,68 +274,14 @@ bool DbTreeModel::refresh_from_database(const FoundSet& found_set)
     Glib::RefPtr<Gnome::Gda::SqlBuilder> sql_query = Utils::build_sql_select_with_where_clause(m_found_set.m_table_name, m_column_fields, m_found_set.m_where_clause, m_found_set.m_extra_join, m_found_set.m_sort_clause, m_found_set.m_extra_group_by);
     //std::cout << "  Debug: DbTreeModel::refresh_from_database():  " << sql_query << std::endl;
 
-    const Application* app = Application::get_application();
-    if(app && app->get_show_sql_debug())
-    {
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
-      try
-      {
-#endif //GLIBMM_EXCEPTIONS_ENABLED
-        std::cout << "Debug: DbTreeModel::refresh_from_database():  " << sql_query << std::endl;
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
-      }
-      catch(const Glib::Exception& ex)
-      {
-        std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
-      }
-#endif //GLIBMM_EXCEPTIONS_ENABLED
-    }
-
-    Glib::RefPtr<Gnome::Gda::SqlParser> parser = m_connection->get_gda_connection()->create_parser();
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
-    try
-    {
-      Glib::RefPtr<Gnome::Gda::Statement> stmt = sql_query->get_statement();
-      //Specify the STATEMENT_MODEL_CURSOR, so that libgda only gets the rows that we actually use.
-      m_gda_datamodel = m_connection->get_gda_connection()->statement_execute_select(stmt, Gnome::Gda::STATEMENT_MODEL_CURSOR_FORWARD);
-      //Examine the columns in the returned DataModel:
-      /*
-      for(int col = 0; col < m_gda_datamodel->get_n_columns(); ++col)
-      {
-        Glib::RefPtr<Gnome::Gda::Column> column = m_gda_datamodel->describe_column(col);
-        std::cout << "  debug: column index=" << col << ", name=" << column->get_name() << ", type=" << g_type_name(column->get_g_type()) << std::endl;
-      }
-      */
-    }
-    catch(const Glib::Exception& ex)
-    {
-      std::cerr << "DbTreeModel::refresh_from_database(): Glib::Exception caught." << std::endl;
-      m_gda_datamodel.reset(); //So that it is 0, so we can handle it below.
-    }
-    catch(const std::exception& ex)
-    {
-      std::cerr << "DbTreeModel::refresh_from_database(): std::exception caught." << std::endl;
-      m_gda_datamodel.reset(); //So that it is 0, so we can handle it below.
-    }
-#else
-    std::auto_ptr<Glib::Error> error;
-    Glib::RefPtr<Gnome::Gda::Statement> stmt = parser->parse_string(sql_query, error);
-    m_gda_datamodel = m_connection->get_gda_connection()->statement_execute_select(stmt, Gnome::Gda::STATEMENT_MODEL_CURSOR_FORWARD, error);
-    if(error.get())
-    {
-      m_gda_datamodel.reset(); //So that it is 0, so we can handle it below.
-    }
-#endif //GLIBMM_EXCEPTIONS_ENABLED
-
-    if(app && app->get_show_sql_debug())
-      std::cout << "  Debug: DbTreeModel::refresh_from_database(): The query execution has finished." << std::endl;
+    m_gda_datamodel = DbUtils::query_execute_select(sql_query, true /* use_cursor */);
 
     if(!m_gda_datamodel)
     {
       m_data_model_rows_count = 0;
       m_data_model_columns_count = m_columns_count;
 
-      std::cerr << "DbTreeModel::refresh_from_database(): error executing SQL: " << sql_query << std::endl;
+      std::cerr << "DbTreeModel::refresh_from_database(): error executing SQL." << std::endl;
       ConnectionPool::handle_error_cerr_only();
       return false; //No records were found.
     }
@@ -964,13 +911,7 @@ void DbTreeModel::get_record_counts(gulong& total, gulong& found) const
       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::DataModel> datamodel = m_connection->get_gda_connection()->statement_execute_select_builder(builder);
-#else
-      std::auto_ptr<Glib::Error> 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
+      Glib::RefPtr<Gnome::Gda::DataModel> datamodel = DbUtils::query_execute_select(builder);
 
       if(datamodel)
       {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]