mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-07-29 15:53:45 -05:00
Implement SubQuery functionality in QOF: qof_query_run_subquery()
Now you can run one query off of the results of another query. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@14901 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
2006-09-26 Derek Atkins <derek@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@ihtfp.com>
|
2006-09-25 Derek Atkins <derek@ihtfp.com>
|
||||||
|
|
||||||
[ Lots of files ]:
|
[ Lots of files ]:
|
||||||
|
|||||||
+67
-22
@@ -682,15 +682,17 @@ void qof_query_purge_terms (QofQuery *q, GSList *param_list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *matching_objects = NULL;
|
||||||
GList *node;
|
|
||||||
int object_count = 0;
|
int object_count = 0;
|
||||||
|
|
||||||
if (!q) return NULL;
|
if (!q) return NULL;
|
||||||
g_return_val_if_fail (q->search_for, NULL);
|
g_return_val_if_fail (q->search_for, NULL);
|
||||||
g_return_val_if_fail (q->books, NULL);
|
g_return_val_if_fail (q->books, NULL);
|
||||||
|
g_return_val_if_fail (run_cb, NULL);
|
||||||
ENTER (" q=%p", q);
|
ENTER (" q=%p", q);
|
||||||
|
|
||||||
/* XXX: Prioritize the query terms? */
|
/* XXX: Prioritize the query terms? */
|
||||||
@@ -712,26 +714,8 @@ GList * qof_query_run (QofQuery *q)
|
|||||||
memset (&qcb, 0, sizeof (qcb));
|
memset (&qcb, 0, sizeof (qcb));
|
||||||
qcb.query = q;
|
qcb.query = q;
|
||||||
|
|
||||||
/* For each book */
|
/* Run the query callback */
|
||||||
for (node=q->books; node; node=node->next)
|
run_cb(&qcb, cb_arg);
|
||||||
{
|
|
||||||
QofBook *book = node->data;
|
|
||||||
QofBackend *be = book->backend;
|
|
||||||
|
|
||||||
/* 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;
|
matching_objects = qcb.list;
|
||||||
object_count = qcb.count;
|
object_count = qcb.count;
|
||||||
@@ -794,6 +778,67 @@ GList * qof_query_run (QofQuery *q)
|
|||||||
return matching_objects;
|
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 *
|
GList *
|
||||||
qof_query_last_run (QofQuery *query)
|
qof_query_last_run (QofQuery *query)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -221,6 +221,16 @@ GList * qof_query_run (QofQuery *query);
|
|||||||
*/
|
*/
|
||||||
GList * qof_query_last_run (QofQuery *query);
|
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
|
/** Remove all query terms from query. query matches nothing
|
||||||
* after qof_query_clear().
|
* after qof_query_clear().
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user