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