glom r1505 - in trunk: . glom glom/libglom/data_structure glom/utility_widgets/db_adddel



Author: murrayc
Date: Tue Apr  1 13:22:57 2008
New Revision: 1505
URL: http://svn.gnome.org/viewvc/glom?rev=1505&view=rev

Log:
2008-04-01  Murray Cumming  <murrayc murrayc com>

* glom/libglom/data_structure/Makefile.am:
* glom/libglom/data_structure/foundset.cc
* glom/libglom/data_structure/foundset.h: Moved FoundSet into its own 
file from base_db.[h|c], because I like that.

* glom/utility_widgets/db_adddel/glom_db_treemodel.cc
* glom/utility_widgets/db_adddel/glom_db_treemodel.h:
* glom/base_db.cc
* glom/base_db.h: Moved count_rows_returned_by() to Base_DB so we 
can use it elsewhere.

* glom/frame_glom.cc Glom.show_table(): Count the approximate number of 
rows expected in the list view, and do not sort them by default if 
it is more than 10,000. This allows Glom to show 600,000 MusicBrainz 
album rows now in 1 minute.

Added:
   trunk/glom/libglom/data_structure/foundset.cc
   trunk/glom/libglom/data_structure/foundset.h
Modified:
   trunk/ChangeLog
   trunk/glom/base_db.cc
   trunk/glom/base_db.h
   trunk/glom/frame_glom.cc
   trunk/glom/libglom/data_structure/Makefile.am
   trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
   trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.h

Modified: trunk/glom/base_db.cc
==============================================================================
--- trunk/glom/base_db.cc	(original)
+++ trunk/glom/base_db.cc	Tue Apr  1 13:22:57 2008
@@ -59,40 +59,6 @@
 namespace Glom
 {
 
-FoundSet::FoundSet()
-{
-}
-
-FoundSet::FoundSet(const FoundSet& src)
-:  m_table_name(src.m_table_name),
-   m_extra_join(src.m_extra_join),
-   m_where_clause(src.m_where_clause),
-   m_extra_group_by(src.m_extra_group_by),
-   m_sort_clause(src.m_sort_clause)
-{
-}
-
-FoundSet& FoundSet::operator=(const FoundSet& src)
-{
-  m_table_name = src.m_table_name;
-  m_extra_join = src.m_extra_join;
-  m_where_clause = src.m_where_clause;
-  m_extra_group_by = src.m_extra_group_by;
-  m_sort_clause = src.m_sort_clause;
-
-  return *this;
-}
-
-bool FoundSet::operator==(const FoundSet& src) const
-{
-  return (m_table_name == src.m_table_name)
-      && (m_extra_join == src.m_extra_join)
-      && (m_where_clause == src.m_where_clause)
-      && (m_extra_group_by == src.m_extra_group_by)
-      && (m_sort_clause == src.m_sort_clause);
-}
-
-
 
 template<class T_Element>
 class predicate_LayoutItemIsEqual
@@ -2707,4 +2673,64 @@
     return false;
 }
 
+int Base_DB::count_rows_returned_by(const Glib::ustring& sql_query)
+{
+  int result = 0;
+
+  //TODO: Is this inefficient?
+  //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";
+  
+  const App_Glom* app = App_Glom::get_application();
+  if(app && app->get_show_sql_debug())
+  { 
+    try
+    {
+      std::cout << "Debug: count_rows_returned_by():  " << query_count << std::endl;
+    }
+    catch(const Glib::Exception& ex)
+    {
+      std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
+    }
+  }
+
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+  sharedptr<SharedConnection> sharedconnection = connect_to_server();
+#else
+  std::auto_ptr<ExceptionConnection> error;
+  sharedptr<SharedConnection> sharedconnection = connect_to_server(0, error);
+  // TODO: Rethrow?
+#endif
+
+  if(!sharedconnection)
+  {
+    g_warning("Base_DB::count_rows_returned_by(): connection failed.");
+    return 0;
+  }
+
+  try
+  {
+    Glib::RefPtr<Gnome::Gda::DataModel> datamodel = sharedconnection->get_gda_connection()->execute_select_command(query_count);
+    if(datamodel && datamodel->get_n_rows() && datamodel->get_n_columns())
+    {
+      Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
+      //This showed me that this contains a gint64: std::cerr << "DEBUG: value type=" << G_VALUE_TYPE_NAME(value.gobj()) << std::endl;
+      result = (int)value.get_int64();
+    }
+  }
+  catch(const Glib::Exception& ex)
+  {
+    std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
+  }
+  catch(const std::exception& ex)
+  {
+    std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
+  }
+
+  //std::cout << "DEBUG: count_rows_returned_by(): Returning " << result << std::endl;
+  return result;
+}
+
+
 } //namespace Glom

Modified: trunk/glom/base_db.h
==============================================================================
--- trunk/glom/base_db.h	(original)
+++ trunk/glom/base_db.h	Tue Apr  1 13:22:57 2008
@@ -28,6 +28,7 @@
 #include <glom/libglom/document/document_glom.h>
 #include <glom/libglom/connectionpool.h>
 #include <glom/libglom/appstate.h>
+#include <glom/libglom/data_structure/foundset.h>
 #include <glom/libglom/data_structure/privileges.h>
 #include <glom/libglom/data_structure/system_prefs.h>
 #include <glom/libglom/utils.h>
@@ -42,25 +43,6 @@
 class LayoutItem_Summary;
 class LayoutItem_VerticalGroup;
 
-class FoundSet
-{
-public:
-  FoundSet();
-  FoundSet(const FoundSet& src);
-  FoundSet& operator=(const FoundSet& src);
-
-  bool operator==(const FoundSet& src) const;
-
-  Glib::ustring m_table_name;
-  Glib::ustring m_extra_join; // Only used for doubly-related related records (portals), in which case the WHERE clause is also slightly different.
-  Glib::ustring m_where_clause;
-  Glib::ustring m_extra_group_by;  // Only used for doubly-related related records (portals), in which case the WHERE clause is also slightly different.
-
-  ///field, ascending
-  typedef std::pair< sharedptr<const LayoutItem_Field>, bool> type_pair_sort_field;
-  typedef std::list<type_pair_sort_field> type_sort_clause;
-  type_sort_clause m_sort_clause;
-};
 
 /** A base class that is a Bakery View with some database functionality.
 */
@@ -98,8 +80,9 @@
   static bool get_field_exists_in_database(const Glib::ustring& table_name, const Glib::ustring& field_name);
 
 
-  //This is const because const means not changing this instance, not whether we change the database.
   static Glib::RefPtr<Gnome::Gda::DataModel> query_execute(const Glib::ustring& strQuery, Gtk::Window* parent_window = 0);
+  static int count_rows_returned_by(const Glib::ustring& sql_query);
+
 
   bool add_standard_groups();
   bool add_standard_tables() const;
@@ -332,10 +315,9 @@
   static bool get_field_primary_key_index_for_fields(const type_vecFields& fields, guint& field_column);
   static bool get_field_primary_key_index_for_fields(const type_vecLayoutFields& fields, guint& field_column);
 
-
-
   static type_vecStrings util_vecStrings_from_Fields(const type_vecFields& fields);
 
+
   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();

Modified: trunk/glom/frame_glom.cc
==============================================================================
--- trunk/glom/frame_glom.cc	(original)
+++ trunk/glom/frame_glom.cc	Tue Apr  1 13:22:57 2008
@@ -348,6 +348,9 @@
 {
   App_Glom* pApp = dynamic_cast<App_Glom*>(get_app_window());
 
+  //This can take quite a long time, so we show the busy cursor while it's working:
+  Bakery::BusyCursor busy_cursor(pApp);
+
   //Check that there is a table to show:
   if(table_name.empty())
   {
@@ -386,7 +389,19 @@
           layout_item_sort->set_full_field_details(field_primary_key);
 
           found_set.m_sort_clause.clear();
-          found_set.m_sort_clause.push_back( type_pair_sort_field(layout_item_sort, true /* ascending */) );
+
+          //Avoid the sort clause if the found set will include too many records, 
+          //because that would be too slow.
+          //The user can explicitly request a sort later, by clicking on a column header.
+          //TODO_Performance: This causes an almost-duplicate COUNT query (we do it in the treemodel too), but it's not that slow. 
+          sharedptr<LayoutItem_Field> layout_item_temp = sharedptr<LayoutItem_Field>::create();
+          layout_item_temp->set_full_field_details(field_primary_key);
+          type_vecLayoutFields layout_fields;
+          layout_fields.push_back(layout_item_temp);
+          const Glib::ustring sql_query_without_sort = Utils::build_sql_select_with_where_clause(found_set.m_table_name, layout_fields, found_set.m_where_clause, found_set.m_extra_join, type_sort_clause(), found_set.m_extra_group_by);
+          const int count = Base_DB::count_rows_returned_by(sql_query_without_sort);
+          if(count < 10000) //Arbitrary large number.
+            found_set.m_sort_clause.push_back( type_pair_sort_field(layout_item_sort, true /* ascending */) );
         }
 
         m_Notebook_Data.init_db_details(found_set, primary_key_value_for_details);
@@ -885,8 +900,10 @@
     m_pBox_Tables->signal_selected.connect(sigc::mem_fun(*this, &Frame_Glom::on_box_tables_selected));
   }
 
-    
-  m_pBox_Tables->init_db_details();
+  {
+    Bakery::BusyCursor busy_cursor(pApp);
+    m_pBox_Tables->init_db_details();
+  }
 
   //Let the user choose a table:
   //m_pDialog_Tables->set_policy(false, true, false); //TODO_port

Modified: trunk/glom/libglom/data_structure/Makefile.am
==============================================================================
--- trunk/glom/libglom/data_structure/Makefile.am	(original)
+++ trunk/glom/libglom/data_structure/Makefile.am	Tue Apr  1 13:22:57 2008
@@ -4,6 +4,7 @@
 
 noinst_LTLIBRARIES = libdata_structure.la
 libdata_structure_la_SOURCES = field.h field.cc \
+                              foundset.h foundset.cc \
                               relationship.h relationship.cc \
                               fieldtypes.h fieldtypes.cc \
                               tableinfo.h tableinfo.cc \

Added: trunk/glom/libglom/data_structure/foundset.cc
==============================================================================
--- (empty file)
+++ trunk/glom/libglom/data_structure/foundset.cc	Tue Apr  1 13:22:57 2008
@@ -0,0 +1,61 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glom/libglom/data_structure/foundset.h>
+
+namespace Glom
+{
+
+FoundSet::FoundSet()
+{
+}
+
+FoundSet::FoundSet(const FoundSet& src)
+:  m_table_name(src.m_table_name),
+   m_extra_join(src.m_extra_join),
+   m_where_clause(src.m_where_clause),
+   m_extra_group_by(src.m_extra_group_by),
+   m_sort_clause(src.m_sort_clause)
+{
+}
+
+FoundSet& FoundSet::operator=(const FoundSet& src)
+{
+  m_table_name = src.m_table_name;
+  m_extra_join = src.m_extra_join;
+  m_where_clause = src.m_where_clause;
+  m_extra_group_by = src.m_extra_group_by;
+  m_sort_clause = src.m_sort_clause;
+
+  return *this;
+}
+
+bool FoundSet::operator==(const FoundSet& src) const
+{
+  return (m_table_name == src.m_table_name)
+      && (m_extra_join == src.m_extra_join)
+      && (m_where_clause == src.m_where_clause)
+      && (m_extra_group_by == src.m_extra_group_by)
+      && (m_sort_clause == src.m_sort_clause);
+}
+
+} //namespace Glom
+
+

Added: trunk/glom/libglom/data_structure/foundset.h
==============================================================================
--- (empty file)
+++ trunk/glom/libglom/data_structure/foundset.h	Tue Apr  1 13:22:57 2008
@@ -0,0 +1,56 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2008 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOM_DATASTRUCTURE_FOUNDSET_H
+#define GLOM_DATASTRUCTURE_FOUNDSET_H
+
+#include <glibmm/ustring.h>
+#include <list>
+#include <utility> //For std::pair
+#include <glom/libglom/data_structure/layout/layoutitem_field.h>
+#include <glom/libglom/sharedptr.h>
+
+namespace Glom
+{
+
+class FoundSet
+{
+public:
+  FoundSet();
+  FoundSet(const FoundSet& src);
+  FoundSet& operator=(const FoundSet& src);
+
+  bool operator==(const FoundSet& src) const;
+
+  Glib::ustring m_table_name;
+  Glib::ustring m_extra_join; // Only used for doubly-related related records (portals), in which case the WHERE clause is also slightly different.
+  Glib::ustring m_where_clause;
+  Glib::ustring m_extra_group_by;  // Only used for doubly-related related records (portals), in which case the WHERE clause is also slightly different.
+
+  ///field, ascending
+  typedef std::pair< sharedptr<const LayoutItem_Field>, bool> type_pair_sort_field;
+  typedef std::list<type_pair_sort_field> type_sort_clause;
+  type_sort_clause m_sort_clause;
+};
+
+} //namespace Glom
+
+#endif //GLOM_DATASTRUCTURE_FOUNDSET_H
+

Modified: trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
==============================================================================
--- trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc	(original)
+++ trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc	Tue Apr  1 13:22:57 2008
@@ -463,51 +463,6 @@
   return Glib::RefPtr<DbTreeModel>( new DbTreeModel(columns, found_set, column_fields, column_index_key, get_records) );
 }
 
-int DbTreeModel::count_rows_returned_by(const Glib::ustring& sql_query)
-{
-  int result = 0;
-
-  //TODO: Is this inefficient?
-  //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";
-  
-  const App_Glom* app = App_Glom::get_application();
-  if(app && app->get_show_sql_debug())
-  { 
-    try
-    {
-      std::cout << "Debug: count_rows_returned_by():  " << query_count << std::endl;
-    }
-    catch(const Glib::Exception& ex)
-    {
-      std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
-    }
-  }
-
-  try
-  {
-    Glib::RefPtr<Gnome::Gda::DataModel> datamodel = m_connection->get_gda_connection()->execute_select_command(query_count);
-    if(datamodel && datamodel->get_n_rows() && datamodel->get_n_columns())
-    {
-      Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
-      //This showed me that this contains a gint64: std::cerr << "DEBUG: value type=" << G_VALUE_TYPE_NAME(value.gobj()) << std::endl;
-      result = (int)value.get_int64();
-    }
-  }
-  catch(const Glib::Exception& ex)
-  {
-    std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
-  }
-  catch(const std::exception& ex)
-  {
-    std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
-  }
-
-  //std::cout << "DEBUG: count_rows_returned_by(): Returning " << result << std::endl;
-  return result;
-}
-
 bool DbTreeModel::refresh_from_database(const FoundSet& found_set)
 {
   //std::cout << "DbTreeModel::refresh_from_database()" << std::endl;
@@ -606,7 +561,7 @@
       //This doesn't work with ITER_MODEL_ONLY: const int count = m_gda_datamodel->get_n_rows();
       //because rows count is -1 until we have iterated to the last row.
       const Glib::ustring sql_query_without_sort = 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, type_sort_clause(), m_found_set.m_extra_group_by);
-      const int count = count_rows_returned_by(sql_query_without_sort);
+      const int count = Base_DB::count_rows_returned_by(sql_query_without_sort);
       if(count < 0)
       {
         std::cerr << "DbTreeModel::refresh_from_database(): count is < 0" << std::endl;

Modified: trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.h
==============================================================================
--- trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.h	(original)
+++ trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.h	Tue Apr  1 13:22:57 2008
@@ -157,8 +157,6 @@
   static gboolean glom_get_iter_impl(GtkTreeModel* model, GtkTreeIter* iter, GtkTreePath* path);
 #endif // !GLIBMM_VUFNCS_ENABLED
 
-   int count_rows_returned_by(const Glib::ustring& query);
-
 private:
    typedef DbTreeModelRow typeRow; //X columns, all of type Value.
 



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