r14901 - gnucash/trunk - Implement SubQuery functionality in QOF: qof_query_run_subquery()

Derek Atkins warlord at cvs.gnucash.org
Tue Sep 26 19:47:09 EDT 2006


Author: warlord
Date: 2006-09-26 19:47:09 -0400 (Tue, 26 Sep 2006)
New Revision: 14901
Trac: http://svn.gnucash.org/trac/changeset/14901

Modified:
   gnucash/trunk/
   gnucash/trunk/ChangeLog
   gnucash/trunk/lib/libqof/qof/qofquery.c
   gnucash/trunk/lib/libqof/qof/qofquery.h
Log:
	  Implement SubQuery functionality in QOF:  qof_query_run_subquery()
	  Now you can run one query off of the results of another query.




Property changes on: gnucash/trunk
___________________________________________________________________
Name: svk:merge
   - 3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/trunk:647
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk:13351
   + 3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/trunk:647
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk:13363

Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2006-09-26 22:20:14 UTC (rev 14900)
+++ gnucash/trunk/ChangeLog	2006-09-26 23:47:09 UTC (rev 14901)
@@ -1,3 +1,9 @@
+2006-09-26  Derek Atkins  <derek at ihtfp.com>
+
+	* lib/libqof/qof/qofquery.[ch]:
+	  Implement SubQuery functionality in QOF:  qof_query_run_subquery()
+	  Now you can run one query off of the results of another query.
+
 2006-09-25  Derek Atkins  <derek at ihtfp.com>
 
 	[ Lots of files ]:

Modified: gnucash/trunk/lib/libqof/qof/qofquery.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery.c	2006-09-26 22:20:14 UTC (rev 14900)
+++ gnucash/trunk/lib/libqof/qof/qofquery.c	2006-09-26 23:47:09 UTC (rev 14901)
@@ -682,15 +682,17 @@
   }
 }
 
-GList * qof_query_run (QofQuery *q)
+static GList * qof_query_run_internal (QofQuery *q,
+				       void(*run_cb)(QofQueryCB*,gpointer),
+				       gpointer cb_arg)
 {
   GList *matching_objects = NULL;
-  GList *node;
   int        object_count = 0;
 
   if (!q) return NULL;
   g_return_val_if_fail (q->search_for, NULL);
   g_return_val_if_fail (q->books, NULL);
+  g_return_val_if_fail (run_cb, NULL);
   ENTER (" q=%p", q);
 
   /* XXX: Prioritize the query terms? */
@@ -712,27 +714,9 @@
     memset (&qcb, 0, sizeof (qcb));
     qcb.query = q;
 
-    /* For each book */
-    for (node=q->books; node; node=node->next) 
-    {
-      QofBook *book = node->data;
-      QofBackend *be = book->backend;
+    /* Run the query callback */
+    run_cb(&qcb, cb_arg);
 
-      /* run the query in the backend */
-      if (be) 
-      {
-        gpointer compiled_query = g_hash_table_lookup (q->be_compiled, book);
-
-        if (compiled_query && be->run_query)
-        {
-          (be->run_query) (be, compiled_query);
-        }
-      }
-
-      /* And then iterate over all the objects */
-      qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb);
-    }
-
     matching_objects = qcb.list;
     object_count = qcb.count;
   }
@@ -794,7 +778,68 @@
   return matching_objects;
 }
 
+static void qof_query_run_cb(QofQueryCB* qcb, gpointer cb_arg)
+{
+  GList *node;
+
+  (void)cb_arg; /* unused */
+  g_return_if_fail(qcb);
+
+  for (node=qcb->query->books; node; node=node->next) 
+  {
+    QofBook *book = node->data;
+    QofBackend *be = book->backend;
+
+    /* run the query in the backend */
+    if (be) 
+    {
+      gpointer compiled_query = g_hash_table_lookup (qcb->query->be_compiled,
+						     book);
+
+      if (compiled_query && be->run_query)
+      {
+	(be->run_query) (be, compiled_query);
+      }
+    }
+
+    /* And then iterate over all the objects */
+    qof_object_foreach (qcb->query->search_for, book,
+			(QofEntityForeachCB) check_item_cb, &qcb);
+  }
+}
+
+GList * qof_query_run (QofQuery *q)
+{
+  /* Just a wrapper */
+  return qof_query_run_internal(q, qof_query_run_cb, NULL);
+}
+
+static void qof_query_run_subq_cb(QofQueryCB* qcb, gpointer cb_arg)
+{
+  QofQuery* pq = cb_arg;
+
+  g_return_if_fail(pq);
+  g_list_foreach(qof_query_last_run(pq), check_item_cb, qcb);
+}
+
 GList *
+qof_query_run_subquery (QofQuery *subq, const QofQuery* primaryq)
+{
+  if (!subq) return NULL;
+  if (!primaryq) return NULL;
+
+  /* Make sure we're searching for the same thing */
+  g_return_val_if_fail (subq->search_for, NULL);
+  g_return_val_if_fail (primaryq->search_for, NULL);
+  g_return_val_if_fail(!safe_strcmp(subq->search_for, primaryq->search_for),
+		       NULL);
+
+  /* Perform the subquery */
+  return qof_query_run_internal(subq, qof_query_run_subq_cb,
+				(gpointer)primaryq);
+}
+
+GList *
 qof_query_last_run (QofQuery *query)
 {
   if (!query)

Modified: gnucash/trunk/lib/libqof/qof/qofquery.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery.h	2006-09-26 22:20:14 UTC (rev 14900)
+++ gnucash/trunk/lib/libqof/qof/qofquery.h	2006-09-26 23:47:09 UTC (rev 14901)
@@ -221,6 +221,16 @@
  */
 GList * qof_query_last_run (QofQuery *query);
 
+/** Perform a subquery, return the results.
+ *  Instead of running over a book, the subquery runs over the results
+ *  of the primary query.
+ *
+ *  Do NOT free the resulting list.  This list is managed internally
+ *  by QofQuery.
+ */
+GList * qof_query_run_subquery (QofQuery *subquery,
+                                const QofQuery* primary_query);
+
 /** Remove all query terms from query.  query matches nothing 
  *  after qof_query_clear().
  */



More information about the gnucash-changes mailing list